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就實現了進程間的通信了