Android進程間通信之--Socket

Socket

Socket是用來進行網絡通信的,並且也可以用來實現跨進程間的通信,只是服務器和主機都在同一臺手機上了

服務端:

ServerSocket mServerSocket = new ServerSocket(port);
Socket socket = mServerSocket.accept();// 代碼運行到這裏了,會等待客戶端的連接

第一行是申明瞭服務器和它的端口號,第二行就是等待客戶端從port端口來連接服務器,連接成功了就會獲得一個socket

客戶端:

Socket socket = new Socket("localhost", port);

使用ip地址和端口號去連接,連接成功了就可以獲得一個socket

數據傳輸:
連接成功過後,在服務端和客戶端都會獲得一個socket的對象,這個對象可以讓我們獲得連接的信息和和輸入輸出流,我們只需要往輸出流中寫入數據,對方就能通過輸入流讀取到數據。至於數據怎麼寫、怎麼定義、怎麼解析,那就是自己的設計或者協議的問題了。接下來我們看一個demo

SocketServicer.java

package com.fht.ada.socket;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import android.content.Intent;
import android.os.IBinder;
import android.os.SystemClock;
import android.util.Log;

public class SocketServicer extends android.app.Service {
    private static final String TAG = "Socket";
    private ServerSocket mServerSocket;
    private static final int port = 44534;
    private ExecutorService mExecutorServicePool;

    public SocketServicer() {
        try {
            mServerSocket = new ServerSocket(port);
        } catch (IOException e) {
            e.printStackTrace();
        }
        // new 線程池
        mExecutorServicePool = Executors.newFixedThreadPool(5);
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        Log.i(TAG, "start SocketServicer");
        // 啓動服務器的時候 我們就啓動一個線程,裏面有一個Socket等待遠程的連接
        new Thread() {
            @Override
            public void run() {
                // 這裏採用while循環,是爲了可以讓多個客戶端一起連接進來
                while (true) {
                    try {
                        Log.i(TAG, "mServerSocket 服務已經啓動,正在等待連接");
                        Socket socket = mServerSocket.accept();// 代碼運行到這裏了,會等待客戶端的連接
                        // 我們把socket放進線程池中進行管理
                        mExecutorServicePool.execute(new SocketHandler(socket));
                        Log.i(TAG, "mServerSocket 連接上了一個");
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                }
            }
        }.start();
    }

    // SocketHandler用來處理每一個連接的socket
    class SocketHandler implements Runnable {
        private Socket mSocket;

        public SocketHandler(Socket socket) {
            mSocket = socket;
        }

        @Override
        public void run() {
            try {
                InputStream in = mSocket.getInputStream();
                InputStreamReader inputStreamReader = new InputStreamReader(in);
                BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
                OutputStream out = mSocket.getOutputStream();

                while (true) {
                    String inputData = bufferedReader.readLine();
                    String reply = mReplyText[point];
                    SystemClock.sleep(1000);
                    point++;
                    point=point%mReplyText.length;
                    out.write((reply + "\n").getBytes());
                    out.flush();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        }

    }

    int point = 0;
    String[] mReplyText = new String[] { "把喜歡兩字去掉才真是造孽", "唉,畢竟不是親生的……", "成雞思漢", "嗯,給你一頭母豬,明年的肉價就能下跌!", "叫犯賤" };

}

ClientActivity.java

package com.fht.ada.socket;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;

import com.fht.ada.R;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.ScrollView;
import android.widget.TextView;

public class ClientActivity extends Activity {
    private static final String TAG = "Socket";
    private static final int port = 44534;
    private TextView mTextView;
    private EditText mEditText;
    private BufferedReader mBufferedReader;
    private OutputStream mOutputStream;
    private ScrollView mScrollView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.setContentView(R.layout.activity_client_socket);
        Intent socketServicer = new Intent(this, SocketServicer.class);
        this.startService(socketServicer);// 啓動服務器
        mTextView = (TextView) this.findViewById(R.id.show_chat);
        mEditText = (EditText) this.findViewById(R.id.input_message);
        mScrollView = (ScrollView) this.findViewById(R.id.scroll_view);
    }

    @Override
    protected void onStart() {
        super.onStart();

    }

    @Override
    protected void onResume() {
        super.onResume();
        connectService();
        mEditText.setText(mIntputText[0]);
    }

    String[] mIntputText = new String[] { "我喜歡上了一個比我小6歲的女孩,還在上初中,真是造孽啊", "我把我家的狗給揍了!地震它也不告訴我,平時叫得那麼歡,剛纔地震時竟像沒事似的在窩裏睡覺!",
            "老婆生了個女娃,非常可愛,求各位幫愛女起個有氣勢的名字,鄙人姓成", "給我一個女人,我就能創造出一個民族!", "分手後的思念不叫思念" };
    int point = 0;

    public void sendMessage(View view) {
        final String inputText = mEditText.getText().toString();
        point++;
        point = point % mIntputText.length;
        mEditText.setText(mIntputText[point]);
        new Thread() {
            @Override
            public void run() {
                try {
                    mOutputStream.write((inputText + "\n").getBytes());
                    mOutputStream.flush();
                    Log.i(TAG, "client:" + inputText);
                    show("client:2016-6-10:\n    " + inputText + "\n");
                    String replyText = mBufferedReader.readLine();
                    Log.i(TAG, "server:" + replyText);
                    show("server:2016-6-10:\n    " + replyText + "\n");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }.start();
    }

    public void connectService() {
        new Thread() {
            public void run() {
                // 我們在onStart()方法中去連接服務器
                while (true) {
                    try {
                        Socket socket = new Socket("localhost", port);
                        InputStream in = socket.getInputStream();
                        InputStreamReader inputStreamReader = new InputStreamReader(in);
                        mBufferedReader = new BufferedReader(inputStreamReader);
                        mOutputStream = socket.getOutputStream();
                        break;
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            };
        }.start();
    }

    public void show(final String s) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Log.i(TAG, mTextView == null ? "null" : "no null");
                mTextView.append(s);
                int offset = mTextView.getMeasuredHeight() - mScrollView.getHeight(); 
                mScrollView.scrollTo(0, offset);
            }
        });
    }
}

activity_client_socket.xml

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

    <ScrollView
        android:id="@+id/scroll_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_above="@+id/input_message"
        android:layout_alignParentTop="true" >

        <TextView
            android:id="@+id/show_chat"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:padding="5dp" />
    </ScrollView>

    <EditText
        android:id="@+id/input_message"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_alignTop="@+id/send_message"
        android:layout_toLeftOf="@+id/send_message"
        android:ems="10" >

        <requestFocus />
    </EditText>

    <Button
        android:id="@+id/send_message"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:onClick="sendMessage"
        android:text="發送" />

</RelativeLayout>

AndroidManifes.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.fht.ada"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="18"
        android:targetSdkVersion="20" />

    <uses-permission android:name="android.permission.GET_TASKS" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
       <activity
            android:name="com.fht.ada.socket.ClientActivity"
            android:label="Socket Client"
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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


        <service
            android:name="com.fht.ada.socket.SocketServicer"
            android:process=":socket" >
            <intent-filter>
                <action android:name="com.fht.ada.socket.SocketServicer" />
            </intent-filter>
        </service>
    </application>

</manifest>

至此,socket就實現了進程間的通信了

源碼下載

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章