安卓 网络编程
Socket服务端客户端
安卓Socket服务端开发注意事项:
网络访问不能在主线程(UI线程)中进行,否则程序会崩溃
要创建线程来发起网络访问
服务端
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class Test {
public static void main(String[] args){
byte[] data = new byte[128];
int len;
try {
ServerSocket socket = new ServerSocket(8888); //创建套接字
System.out.println("套接字建立成功 等待连接");
while(true){
final Socket con = socket.accept(); // 连接
System.out.println("有数据接入");
new Thread(new Runnable() { //创建线程来发起网络访问
public void run() {
// TODO Auto-generated method stub
InputStream in; // 获取数据接收通道
OutputStream out; // 获得数据发送通道
try {
in = con.getInputStream();
byte[] data = new byte[128];
int len = 0;
len = in.read(data);
System.out.println("读到数据:"+new String(data, 0, len));
out = con.getOutputStream();
Scanner sc = new Scanner(System.in);
String message = sc.next();
out.write(message.getBytes());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
客户端
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
try {
Socket client = new Socket("192.168.106.1", 8888); //连接
OutputStream out = client.getOutputStream(); // 获得数据发送通道
Scanner sc = new Scanner(System.in);
String message = sc.next();
out.write(message.getBytes());
InputStream in = client.getInputStream();
int len;
byte[] data = new byte[128];
len = in.read(data);
System.out.println("获取服务单的数据"+new String(data, 0, len));
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
安卓Socket客户端1——实现类似前后左右控制小车
MainActivity.java
package com.example.linmu.learn;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import com.example.linmu.learn.nets.Test;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void command(View v){
switch(v.getId()){
case R.id.go:
Test.sendmessagehandle("go");
break;
case R.id.back:
Test.sendmessagehandle("back");
break;
case R.id.left:
Test.sendmessagehandle("left");
break;
case R.id.right:
Test.sendmessagehandle("right");
break;
}
}
}
Test.java
package com.example.linmu.learn.nets;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
public class Test {
public static void sendmessagehandle(final String string){
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
Socket client = new Socket("192.168.106.1", 8888); //连接
OutputStream out = client.getOutputStream(); // 获得数据发送通道
String message = string;
out.write(message.getBytes());
// InputStream in = client.getInputStream();
// int len;
// byte[] data = new byte[128];
// len = in.read(data);
// System.out.println("获取服务单的数据"+new String(data, 0, len));
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
}
activity_main.xml
<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:background="@drawable/beijing"
tools:context=".MainActivity" >
<Button
android:id="@+id/go"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/back"
android:layout_alignParentTop="true"
android:layout_marginTop="133dp"
android:background="#8a2be2"
android:onClick="command"
android:text="前进" />
<Button
android:id="@+id/right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/go"
android:layout_marginLeft="15dp"
android:layout_marginTop="27dp"
android:layout_toRightOf="@+id/go"
android:background="#8a2be2"
android:onClick="command"
android:text="右转" />
<Button
android:id="@+id/left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/right"
android:layout_alignBottom="@+id/right"
android:layout_toLeftOf="@+id/go"
android:background="#8a2be2"
android:onClick="command"
android:text="左转" />
<Button
android:id="@+id/back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/left"
android:layout_centerHorizontal="true"
android:layout_marginTop="32dp"
android:background="#8a2be2"
android:onClick="command"
android:text="后退" />
</RelativeLayout>
效果
实现倒计时(通过Handler)
Handler的工作机制
1.Message 消息,理解为线程间通讯的数据单元。例如后台子线程在处理数据完毕后需要更新UI,则可发送一条包含更新信息的Message给UI线程。
2.Message Queue 消息队列,用来存放通过Handler发布的消息,按照先进先出执行。
3.Handler是Message的主要处理者,负责将Message添加到消息队列以及对消- 息队列中的Message进行处理。
4.Looper 循环器,扮演Message Queue和Handler之间桥梁的角色,循环取出Message
Queue里面的Message,并交付给相应的Handler进行处理。
抽象来说就是UI主线程家里的“电话”,处理一些其他进程不能处理的事件
package com.example.linmu;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.TextView;
public class MainActivity extends Activity {
public Handler h;
public TextView textview;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textview = (TextView) findViewById(R.id.textview);
h = new Handler(){ // UI主线程家里的电话,处理一些其他进程不能处理的事件
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
textview.setText(msg.what+"s");
}
};
}
public void start(View v){
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
for (int i = 9; i > -1; i--) {
Message msg = new Message();
msg.what = i;
h.sendMessage(msg); // "打电话"去把UI要显示,要处理的事交给线程的handler去做
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}).start();
}
}
安卓Socket客户端2——显示服务端发来的数据能不断刷新
MainActivity.java
package com.example.linmu.learn;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.TextView;
import com.example.linmu.learn.nets.Test;
public class MainActivity extends Activity {
Handler h;
TextView textview;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textview = (TextView) findViewById(R.id.textview);
h = new Handler(){
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
Bundle b = msg.getData();
String string = b.getString("msg");
textview.setText(string); //显示数据
}
};
}
public void start(View v){
switch(v.getId()){
case R.id.button1:
Test.sendmessagehandle("goforward", h);
break;
}
}
}
Test.java
package com.example.linmu.learn.nets;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
public class Test {
public static void sendmessagehandle(final String string, final Handler h){
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
Socket client = new Socket("192.168.106.1", 8888); //连接
OutputStream out = client.getOutputStream(); // 获得数据发送通道
String message = string;
out.write(message.getBytes());
InputStream in = client.getInputStream(); //获得数据发送通道
int len;
byte[] data = new byte[128];
len = in.read(data);
String str = new String(data,0,len);
Message msg = new Message();
Bundle b = new Bundle();
b.putString("msg", str);
msg.setData(b);
h.sendMessage(msg); //去把UI要显示,要处理的事交给线程的handler去做
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
}
activity_main.xml
<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:background="#000000"
tools:context=".MainActivity" >
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:onClick="start"
android:text="发起网络请求" />
<TextView
android:id="@+id/textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textColor="#ffffff"
android:textSize="35dp"
android:textStyle="bold"
android:text="666"
/>
</RelativeLayout>