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代码差不多。

运行效果:


评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值