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 blocke.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 blocke.printStackTrace();}//獲取輸入流,用來讀取數據,返回值是InputStream類型}}).start();}} catch (IOException e) {// TODO Auto-generated catch blocke.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 blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.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;@Overrideprotected 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 blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} }@Overridepublic void onClick(View arg0) {//因為網絡訪問不可以放到主線程里面,否則會拋出異常new Thread(new Runnable() { @Overridepublic 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;@Overrideprotected 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(){@Overridepublic void handleMessage(Message msg) {//區分事件的類型,Handler有點像UI主線程的家里的電話,他接到電話后去處理其他進程無法處理的事件(比如說在其他線程修改UI)// TODO Auto-generated method stubsuper.handleMessage(msg);text.setText(String.valueOf(msg.arg1));} };}@Overridepublic void onClick(View v) {// TODO Auto-generated method stubnew Thread(new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stubfor (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 blocke.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是一個類@Overrideprotected 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() {@Overridepublic void handleMessage(Message msg2) {// 區分事件的類型,Handler有點像UI主線程的家里的電話,他接到電話后去處理其他進程無法處理的事件(比如說在其他線程修改UI)// TODO Auto-generated method stubsuper.handleMessage(msg2);Bundle b=msg2.getData();text.setText(b.getString("data"));}};}@Overridepublic void onClick(View v) {// TODO Auto-generated method stubnew Thread(new Runnable() {@Overridepublic 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 blocke.printStackTrace();}} catch (UnknownHostException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}).start();}
}
WebView控件之自制瀏覽器App:
- 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;@Overrideprotected 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;@Overrideprotected 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顯示網頁,則必須設置}
}