Socket服务端简单地API:
- 主要用到以下几个API:
ServerSocket
用来设置端口号、accept
用来和服务端连接、getInputStream
用来获取输入流、read
用来读取输入流里面的数据,存放在提前开辟好的缓冲区里面。
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Main {
public static void main(String[] args){
byte[] data=new byte[128];
int len=0;
//创建套接字,设置IP和端口号
try {
ServerSocket socket =new ServerSocket(8887);//8888是端口号
System.out.println("Socket套接字创建成功等待连接");
Socket con=socket.accept(); //con相当于连接通道是Socket类型
System.out.println("有客户端接入");
InputStream in=con.getInputStream();//获取输入流,用来读取数据,返回值是InputStream类型
len=in.read(data);
System.out.println("读到消息:"+new String(data,0,len));//String()这个构造方法里面有基于Byte组建一个字符串
//上面代表从第0个开始至第len个进行转化为字符串
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}//
}
}
建立Socket单点多连接,实现数据的多次发送:
这个主要用一个while循环,不断接收客户端的接入,当有新的客户端接入的时候就会创建一个新的线程去和新接入的客户端对接,然后将接受的数据打印出来
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Main {
public static void main(String[] args){
//创建套接字,设置IP和端口号
try {
ServerSocket socket =new ServerSocket(8887);//8888是端口号
System.out.println("Socket套接字创建成功等待连接");
while(true){//实现while循环不断接受连接
final Socket con=socket.accept(); //con相当于连接通道是Socket类型,这里需要将其设置为final类型
System.out.println("有客户端接入");
new Thread(new Runnable() {
public void run() {
InputStream in;
try {
byte[] data=new byte[128];
int len=0;
in = con.getInputStream();
len=in.read(data);
System.out.println("读到消息:"+new String(data,0,len));//String()这个构造方法里面有基于Byte组建一个字符串
//上面代表从第0个开始至第len个进行转化为字符串
} catch (IOException e) {//可能出现数据流读取错误,所以要设置异常处理
// TODO Auto-generated catch block
e.printStackTrace();
}//获取输入流,用来读取数据,返回值是InputStream类型
}
}).start();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}//
}
}
Socket客户端实现收发数据:
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 Main {
public static void main(String[] args) {
try {
Socket Client=new Socket("192.168.43.227",8880); //去连接IP地址是192.168.43.227端口号是8887的服务器
OutputStream out=Client.getOutputStream(); //用getOutputStream这个方法去发送数据返回值是OutputStream类型,就获得一个向外输出的一个通道
System.out.println("请输入数据:");
Scanner input=new Scanner(System.in);
String message=input.next();
out.write(message.getBytes());//message.getBytes将返回值转化为Byte类型的数组,进行发送
//实现客户端接收数据
byte[] data=new byte[128];
int len;
InputStream in=Client.getInputStream(); //获得数据接收通道
len=in.read(data);
System.out.println("获得服务端返回信息:"+new String(data,0,len));
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
实现安卓Socket给服务器传输数据:
- 注意网络访问不可以放到主线程里面,否则会抛出异常
package com.fhn.socket;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends Activity implements View.OnClickListener {
Button btn1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn1=(Button)findViewById(R.id.b);
btn1.setOnClickListener(this);
}
public void SendMessage(){
try {
String message="message from Andriod";
Socket Client=new Socket("192.168.43.227",8881); //去连接IP地址是192.168.43.227端口号是8887的服务器
OutputStream out=Client.getOutputStream(); //用getOutputStream这个方法去发送数据返回值是OutputStream类型,就获得一个向外输出的一个通道
out.write(message.getBytes());//message.getBytes将返回值转化为Byte类型的数组,进行发送
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void onClick(View arg0) {//因为网络访问不可以放到主线程里面,否则会抛出异常
new Thread(new Runnable() {
@Override
public void run() {
SendMessage();
}
}).start();
}
}
安卓非UI线程修改控件:
- 睡眠不能在主线程里面睡眠,得另外开启一个线程,但是新建的线程不能去修改TextView,否则程序会崩掉
- 使用
Handler
类去修改UI界面的控件,在另一个线程里面相当于发送消息到UI线程让其修改控件。
package com.fhn.fefsh;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity implements View.OnClickListener{
TextView text;
Button btn1;
Handler h; //Handler是一个类
int i=0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text=(TextView)findViewById(R.id.textview);
btn1=(Button)findViewById(R.id.b1);
btn1.setOnClickListener(this);
h=new Handler(){
@Override
public void handleMessage(Message msg) {//区分事件的类型,Handler有点像UI主线程的家里的电话,他接到电话后去处理其他进程无法处理的事件(比如说在其他线程修改UI)
// TODO Auto-generated method stub
super.handleMessage(msg);
text.setText(String.valueOf(msg.arg1));
}
};
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
for (int i = 0; i <10; i++) {
Message msg=new Message();
msg.arg1=i;//设置message的内容
//打电话,去把UI要显示,要处理的事件交给UI线程的Handler去做
h.sendMessage(msg);
try {
Thread.sleep(2000);//睡眠不能在主线程里面睡眠,得另外开启一个线程,但是新建的线程不能去修改TextView,否则程序会崩掉
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}).start();
}
}
安卓接收数据并刷新界面:
package com.fhn.fefsh;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity implements View.OnClickListener {
TextView text;
Button btn1;
Handler h; // Handler是一个类
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text = (TextView) findViewById(R.id.textview);
btn1 = (Button) findViewById(R.id.b1);
btn1.setOnClickListener(this);
h = new Handler() {
@Override
public void handleMessage(Message msg2) {// 区分事件的类型,Handler有点像UI主线程的家里的电话,他接到电话后去处理其他进程无法处理的事件(比如说在其他线程修改UI)
// TODO Auto-generated method stub
super.handleMessage(msg2);
Bundle b=msg2.getData();
text.setText(b.getString("data"));
}
};
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
new Thread(new Runnable() {
@Override
public void run() {
try {
Socket Client = new Socket("192.168.43.227", 8883); // 去连接IP地址是192.168.43.227端口号是8887的服务器
OutputStream out = Client.getOutputStream(); // 用getOutputStream这个方法去发送数据返回值是OutputStream类型,就获得一个向外输出的一个通道
// 实现客户端接收数据
byte[] data = new byte[128];
int len;
InputStream in = Client.getInputStream(); // 获得数据接收通道
len = in.read(data);
System.out.println("获得服务端返回信息:" + new String(data, 0, len));
String getmsg = new String(data, 0, len);
Message msg = new Message();
Bundle bun = new Bundle();
bun.putString("data", getmsg);
msg.setData(bun);// 设置message的内容
// 打电话,去把UI要显示,要处理的事件交给UI线程的Handler去做
h.sendMessage(msg);
try {
Thread.sleep(1000);// 睡眠不能在主线程里面睡眠,得另外开启一个线程,但是新建的线程不能去修改TextView,否则程序会崩掉
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
}
- WebView概述: Android WebView在Android平台上是一个特殊的View,它能用来显示网页,这个WebView类可以被用来在app中仅仅显示一张在线的网页,当然还可以用来开发浏览器。WebView内部实现是采用渲染引擎(WebKit)来展示view的内容,提供网页前进后退、网页放大、缩小、搜索等功能。WebView是一个基于WebKit引擎、展现Web页面的控件,Android的WebView在低版本和高版本采用了不同的WebKit版本内核。
- WebView的基本使用:①: 在布局文件中添加WebView控件 ②: 在代码中让WebView控件加载显示网页。当然,在这里,我们需要加载网络上的数据内容,因此还需要添加网络权限:
<!-- 添加网络权限 --> <uses-permission android:name="android.permission.INTERNET" />
- 实现从APP访问百度:
package com.fhn.baidu;
import android.app.Activity;
import android.os.Bundle;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class MainActivity extends Activity {
WebView wb;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
wb=(WebView)findViewById(R.id.wv_webview);
wb.loadUrl("http://www.baidu.com");
wb.setWebViewClient(new WebViewClient());// //系统默认会通过手机浏览器打开网页,为了能够直接通过WebView显示网页,则必须设置
}
}
- EditText把回车键变成搜索
在xml文件中的EditText中添加
android:imeOptions="actionSearch" 属性
et_main_search.setOnKeyListener(new OnKeyListener() {//输入完后按键盘上的搜索键【回车键改为了搜索键】
public boolean onKey(View v, int keyCode, KeyEvent event) {
if(keyCode==KeyEvent.KEYCODE_ENTER){//改动回车键功能
}
return false;
}
});
实现自定义网址访问:
package com.fhn.baidu;
import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnKeyListener;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends Activity {
EditText edit1;
WebView wb;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
wb=(WebView)findViewById(R.id.wv_webview);
wb.setWebViewClient(new WebViewClient());
edit1=(EditText)findViewById(R.id.edittext);
edit1.setOnKeyListener(new OnKeyListener() {//输入完后按键盘上的搜索键【回车键改为了搜索键】
public boolean onKey(View v, int keyCode, KeyEvent event) {
if(keyCode==KeyEvent.KEYCODE_ENTER){//修改回车键功能
Toast.makeText(MainActivity.this, "回车", Toast.LENGTH_LONG).show();
String str=edit1.getText().toString();
System.out.println(str);
wb.loadUrl(str);
}
return false;
}
});
// wb.loadUrl("http://www.baidu.com");
// wb.setWebViewClient(new WebViewClient());// //系统默认会通过手机浏览器打开网页,为了能够直接通过WebView显示网页,则必须设置
}
}