android客户端在多个界面切换时保持socket的链接的实例

鉴于自己的痛苦,研究一个socket在多个界面切换时保持链接的问题,令我纠结很久,现在我提供客户端的源码给有需要的人参考。

1、ApplicationUtil类:

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

import android.app.Application;

public class ApplicationUtil extends Application{

    private Socket socket;
    private DataOutputStream out = null;
    private DataInputStream in = null;

    public void init() throws IOException, Exception{
        this.socket = new Socket("192.168.1.104",10202);
        this.out = new DataOutputStream(socket.getOutputStream());
        this.in = new DataInputStream(socket.getInputStream());
    }

    public Socket getSocket() {
        return socket;
    }

    public void setSocket(Socket socket) {
        this.socket = socket;
    }

    public DataOutputStream getOut() {
        return out;
    }

    public void setOut(DataOutputStream out) {
        this.out = out;
    }

    public DataInputStream getIn() {
        return in;
    }

    public void setIn(DataInputStream in) {
        this.in = in;
    }

}

AndroidMainifest.xml中application的配置:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.login"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="10"
        android:targetSdkVersion="15" />

    <application
        android:name="com.util.ApplicationUtil"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >

    <activity
            android:name=".LoginActivity"
            android:label="@string/title_activity_main" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
      <activity android:name=".MainActivity"/>

    </application>

    <!-- 振动需要的权限 -->
     <uses-permission android:name="android.permission.VIBRATE"/>
 <!-- 声明网络权限 -->
    <uses-permission android:name="android.permission.INTERNET"/>
</manifest>

2、LoginActivity类:

import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

import com.login.R;
import com.util.ApplicationUtil;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class LoginActivity extends Activity{

    private EditText usernameT;
    private EditText passwordT;
    private Button loginButton;
    private Socket socket;
    private DataOutputStream out;
    private DataInputStream in;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.login);

        usernameT = (EditText) findViewById(R.id.username);
        passwordT = (EditText) findViewById(R.id.password);
        loginButton = (Button) findViewById(R.id.login);

        loginButton.setOnClickListener(new OnClickListener(){
            public void onClick(View v) {

                ApplicationUtil appUtil =  (ApplicationUtil) LoginActivity.this.getApplication();
                try {
                    appUtil.init();
                    Socket socket = appUtil.getSocket();
                    out = appUtil.getOut();
                    in = appUtil.getIn();

                } catch (IOException e1) {
                    e1.printStackTrace();
                } catch (Exception e1) {
                    e1.printStackTrace();
                }

                String username = usernameT.getText().toString();
                String password = passwordT.getText().toString();
                MD5 md5 = new MD5();
                String ss = md5.MD5(username+"|"+password);

                try {
                    //发送数据
                    String str = "[login]|"+ss;
                    out.writeBytes(str);
                    out.flush();
                    System.out.println("str ===> "+str);
                     //创建一个缓冲字节数
                    int r = in.available();
                    while(r==0){
                     r = in.available();
                    }
                    byte[] b = new byte[r];
                    in.read(b);
                    String result = new String(b,"utf-8");
                    System.out.println("result = "+result);
                    if(result.equals("登陆成功0")){
                        Intent intent = new Intent();
                        intent.setClass(LoginActivity.this, MainActivity.class);
                        startActivity(intent);
                    }
                    else
                    {
                        Intent intent = new Intent();
                        intent.setClass(LoginActivity.this, MainActivity.class);
                        startActivity(intent);
                    }

                } catch (UnknownHostException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });

    }
}

3、MainActivity类:

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;

import com.image.TestActivity;
import com.login.R;
import com.util.ApplicationUtil;

import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.provider.MediaStore.Audio;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends Activity {

    private EditText mess;
    private Socket socket;
    private Handler handler;
    private DataInputStream in;

     private NotificationManager nm;
     private Notification n;
     private int messageNotificationID = 0;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.success);
        mess = (EditText) findViewById(R.id.message);

        ApplicationUtil appUtil = (ApplicationUtil) MainActivity.this.getApplication();
        socket = appUtil.getSocket();
        in = appUtil.getIn();

        handler = new Handler(){
            @Override
            public void handleMessage(Message msg) {
                //如果来自子线程
                if(msg.what == 0x123){
                    mess.append(msg.obj.toString()+"\n");
                    //消息通知
                    mynoti();
                }
            }
        };
        //调用线程
        myThread();

   }
    //JAVA可以设置读写缓冲区的大小-setReceiveBufferSize(int size), setSendBufferSize(int size)。
    public void myThread(){
        Thread oneThread = new Thread(new Runnable(){
             public boolean isRunning = true;
            public void run() {
                while(isRunning){
                try {
                    Thread.sleep(1000);
                     //创建一个缓冲字节数
                    int r = in.available();
                    while(r==0){
                         r = in.available();
                        }
                    byte[] b = new byte[r];
                    in.read(b);
                    String content = new String(b,"utf-8");
                        //每当读到来自服务器的数据后,发送消息通知程序页面显示数据
                        Message msg = new Message();
                        msg.what = 0x123;
                        msg.obj = content;
                        Log.v("ho", content);
                        handler.sendMessage(msg);

                } catch (IOException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            }
        });
        oneThread.start();
    }

    public void mynoti(){
             NotificationManager mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
            // 创建一个通知
            Notification mNotification = new Notification();
            //用系统自带的铃声
            mNotification.sound = Uri.withAppendedPath(Audio.Media.INTERNAL_CONTENT_URI, "6");
            // mNotification.sound = Uri.parse("file:///sdcard/wen.mp3");
            //mNotification.defaults=Notification.DEFAULT_SOUND;  

            //Notification.FLAG_INSISTENT;      //让声音、振动无限循环,直到用户响应
            //Notification.FLAG_AUTO_CANCEL;    //通知被点击后,自动消失
            //Notification.FLAG_NO_CLEAR;  //点击‘Clear‘时,不清楚该通知(QQ的通知无法清除,就是用的这个)
            mNotification.flags = Notification.FLAG_NO_CLEAR; ;  

            //通知时发出的振动
            //第一个参数: 振动前等待的时间
            //第二个参数: 第一次振动的时长、以此类推
            long[] vir = {0,100,200,300};
            mNotification.vibrate = vir;  

            mNotificationManager.notify(messageNotificationID, mNotification);
            messageNotificationID++;
    }
}

4、MD5类:

import java.security.MessageDigest;

public class MD5 {

     // MD5加码。32位
     public static String MD5(String inStr) {
      MessageDigest md5 = null;
      try {
       md5 = MessageDigest.getInstance("MD5");
      } catch (Exception e) {
       System.out.println(e.toString());
       e.printStackTrace();
       return "";
      }
      char[] charArray = inStr.toCharArray();
      byte[] byteArray = new byte[charArray.length];     

      for (int i = 0; i < charArray.length; i++)
       byteArray[i] = (byte) charArray[i];     

      byte[] md5Bytes = md5.digest(byteArray);     

      StringBuffer hexValue = new StringBuffer();     

      for (int i = 0; i < md5Bytes.length; i++) {
       int val = ((int) md5Bytes[i]) & 0xff;
       if (val < 16)
        hexValue.append("0");
       hexValue.append(Integer.toHexString(val));
      }
      return hexValue.toString();
     }
}

6、login.xml和success.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

        <TableLayout
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
            >
        <TableRow>
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="账号:"
                />
       <EditText
            android:id="@+id/username"
            android:layout_width="200dp"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:layout_marginTop="10dp"
            android:layout_marginRight="10dp"
            android:hint="账号"
        />
         </TableRow>
         <TableRow>
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="密码:"
                />
        <EditText
            android:id="@+id/password"
            android:password="true"
            android:layout_width="200dp"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:layout_marginTop="10dp"
            android:layout_marginRight="10dp"
            android:hint="密码"
        />
         </TableRow>  

        </TableLayout>
         <Button
            android:id="@+id/login"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:layout_marginTop="10dp"
            android:layout_marginRight="10dp"
            android:text="登录"
    />

</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/success"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="不断接受信息,并提示"
        />
    <EditText
        android:id="@+id/message"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:cursorVisible="false"
        />
    </LinearLayout>

以上都是客户端,服务端就自己写,socket代码差不多。

时间: 2024-10-05 04:19:16

android客户端在多个界面切换时保持socket的链接的实例的相关文章

Android Viewpager加Fragment做界面切换时数据消失的解决方式

今天遇到多个Fragment切换,回来后页面空白的情况,找到这个博客方法设置了一下,就可以了 [java] view plain copy vpAdapter = new VpAdapter(getSupportFragmentManager(), fragments); vp_content.setAdapter(vpAdapter); vp_content.setOffscreenPageLimit(2);//设置ViewPage缓存界面数 原文地址:https://www.cnblogs.

android开发之activity横竖屏切换时的生命周期以及横竖屏切换时的资源适配方案

背景:之前有过两篇写activity的博客 android之activity的生命周期详解:详细介绍了activity的整个生命周期.各状态间的转换和返回桌面时保存activity的状态 android之activity中onSaveInstanceState和onRestoreInstanceState的触发时机:介绍了activity中这两个方法的触发时机和作用 本篇博客会牵扯到里面的内容,如果你都有所了解可以直接往下看,如果不了解可以进去回忆下. 问题:在做应用的退出对话框时,发现如果对话

[Android Pro] Fragment中使用SurfaceView切换时闪一下黑屏的解决办法

方法一.在Activity的onCreate中添加如下代码 getWindow().setFormat(PixelFormat.TRANSLUCENT); reference to :  http://www.jb51.net/article/72719.htm

FragmentCustomAnimation实现Fragment的界面切换

1.知识点:FragmentCustomAnimation 2.演示样例:来自于官网演示样例的简化,这样更方便于学习该知识点. 本演示样例的源代码下载地址为:http://download.csdn.net/detail/far_sight/7932287 3.项目FragmentCustomAnimationTest1效果:反复点buttonnew fragment,第点一次,数字加一,实现原因是第点一次加了一个新的Fragment在栈中. 当点返回键时,数字会降低,原因是Fragment在出

emWin 界面切换注意事项

@2018-7-10  emWin 在做界面切换时,须将切换前的界面所有信息 "删除",否则将造成切换后的界面死机 此 "删除" 对象包括: > 界面上绘制的曲线(随时间一直变化).绘制的2D图形()等,这些对象都是动态刷新的非静态 > ... 原文地址:https://www.cnblogs.com/skullboyer/p/9290647.html

android viewpager fragment切换时界面卡顿解决办法

目前开发的程序在切换View时界面卡顿现象比较严重,影响用户体验,当前项目共就四个View,每个View也只是按钮,所以可以同时加载,不让其它view销毁. 只需在Adapter中重载destroyItem类即可 @Override public void destroyItem(ViewGroup container, int position, Object object) { //重载该方法,防止其它视图被销毁,防止加载视图卡顿 //super.destroyItem(container,

高仿优酷Android客户端图片左右滑动(自动切换)

本例是用ViewPager去做的实现,支持自动滑动和手动滑动,不仅优酷网,实际上有很多商城和门户网站都有类似的实现: 具体思路: 1. 工程中需要添加android-support-v4.jar,才能使用ViewPager控件. 2. 图片的自动切换: 可使用Timer或者ScheduledExecutorService,这个有多重方式可以实现. 同时要切换底部的dots(园点) 3.Handler+Message机制更新UI,这个相信大家都很熟练,不再描述 4. 实现的一些细节:注意本例中的优

Android Activity界面切换添加动画特效

在Android 2.0之后有了overridePendingTransition() ,其中里面两个参数,一个是前一个activity的退出两一个activity的进入, Java代码   @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.SplashScreen); new Handler().postD

Android解决多个Fragment切换时布局重新实例化问题

本文借鉴自:http://www.jianshu.com/p/d9143a92ad94 至于fragment的使用就不多说了,直奔主题, 布局文件: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_pare