編輯:關於Android編程
1.廢話不多說,附主要的Client類[ package com.boyaa.push.lib.service; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketException; import java.util.Iterator; import java.util.concurrent.LinkedBlockingQueue; import android.content.Context; import android.util.Log; import com.boyaa.push.lib.util.NetworkUtil; /** * * @author Administrator * */ public class Client { private final int STATE_OPEN=1;//socket打開 private final int STATE_CLOSE=1<<1;//socket關閉 private final int STATE_CONNECT_START=1<<2;//開始連接server private final int STATE_CONNECT_SUCCESS=1<<3;//連接成功 private final int STATE_CONNECT_FAILED=1<<4;//連接失敗 private final int STATE_CONNECT_WAIT=1<<5;//等待連接 private String IP="192.168.1.100"; private int PORT=60000; private int state=STATE_CONNECT_START; private Socket socket=null; private OutputStream outStream=null; private InputStream inStream=null; private Thread conn=null; private Thread send=null; private Thread rec=null; private Context context; private ISocketResponse respListener; private LinkedBlockingQueue<Packet> requestQueen=new LinkedBlockingQueue<Packet>(); private final Object lock=new Object(); public int send(Packet in) { requestQueen.add(in); synchronized (lock) { lock.notifyAll(); } return in.getId(); } public void cancel(int reqId) { Iterator<Packet> mIterator=requestQueen.iterator(); while (mIterator.hasNext()) { Packet packet=mIterator.next(); if(packet.getId()==reqId) { mIterator.remove(); } } } public Client(Context context,ISocketResponse respListener) { this.context=context; this.respListener=respListener; } public boolean isNeedConn() { return !((state==STATE_CONNECT_SUCCESS)&&(null!=send&&send.isAlive())&&(null!=rec&&rec.isAlive())); } public void open() { reconn(); } public void open(String host,int port) { this.IP=host; this.PORT=port; reconn(); } private long lastConnTime=0; public synchronized void reconn() { if(System.currentTimeMillis()-lastConnTime<2000) { return; } lastConnTime=System.currentTimeMillis(); close(); state=STATE_OPEN; conn=new Thread(new Conn()); conn.start(); } public synchronized void close() { if(state!=STATE_CLOSE) { try { if(null!=socket) { socket.close(); } } catch (Exception e) { e.printStackTrace(); }finally{ socket=null; } try { if(null!=outStream) { outStream.close(); } } catch (Exception e) { e.printStackTrace(); }finally{ outStream=null; } try { if(null!=inStream) { inStream.close(); } } catch (Exception e) { e.printStackTrace(); }finally{ inStream=null; } try { if(null!=conn&&conn.isAlive()) { conn.interrupt(); } } catch (Exception e) { e.printStackTrace(); }finally{ conn=null; } try { if(null!=send&&send.isAlive()) { send.interrupt(); } } catch (Exception e) { e.printStackTrace(); }finally{ send=null; } try { if(null!=rec&&rec.isAlive()) { rec.interrupt(); } } catch (Exception e) { e.printStackTrace(); }finally{ rec=null; } state=STATE_CLOSE; } requestQueen.clear(); } private class Conn implements Runnable { public void run() { while(state!=STATE_CLOSE) { try { state=STATE_CONNECT_START; socket=new Socket(); socket.connect(new InetSocketAddress(IP, PORT), 15*1000); state=STATE_CONNECT_SUCCESS; } catch (Exception e) { e.printStackTrace(); state=STATE_CONNECT_FAILED; } if(state==STATE_CONNECT_SUCCESS) { try { outStream=socket.getOutputStream(); inStream=socket.getInputStream(); } catch (IOException e) { e.printStackTrace(); } send=new Thread(new Send()); rec=new Thread(new Rec()); send.start(); rec.start(); break; } else { state=STATE_CONNECT_WAIT; //如果有網絡沒有連接上,則定時取連接,沒有網絡則直接退出 if(NetworkUtil.isNetworkAvailable(context)) { try { Thread.sleep(15*1000); } catch (InterruptedException e) { e.printStackTrace(); break; } } else { break; } } } } } private class Send implements Runnable { public void run() { try { while(state!=STATE_CLOSE&&state==STATE_CONNECT_SUCCESS&&null!=outStream) { Packet item; while(null!=(item=requestQueen.poll())) { outStream.write(item.getPacket()); outStream.flush(); item=null; } synchronized (lock) { lock.wait(); } } }catch(SocketException e1) { e1.printStackTrace();//發送的時候出現異常,說明socket被關閉了(服務器關閉)java.net.SocketException: sendto failed: EPIPE (Broken pipe) reconn(); } catch (Exception e) { e.printStackTrace(); } } } private class Rec implements Runnable { public void run() { try { while(state!=STATE_CLOSE&&state==STATE_CONNECT_SUCCESS&&null!=inStream) { byte[] bodyBytes=new byte[5]; int offset=0; int length=5; int read=0; while((read=inStream.read(bodyBytes, offset, length))>0) { if(length-read==0) { if(null!=respListener) { respListener.onSocketResponse(new String(bodyBytes)); } offset=0; length=5; read=0; continue; } offset+=read; length=5-offset; } reconn();//走到這一步,說明服務器socket斷了 break; } } catch(SocketException e1) { e1.printStackTrace();//客戶端主動socket.close()會調用這裡 java.net.SocketException: Socket closed } catch (Exception e2) { e2.printStackTrace(); } } } } package com.boyaa.push.lib.service;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketException;
import java.util.Iterator;
import java.util.concurrent.LinkedBlockingQueue;
import android.content.Context;
import android.util.Log;
import com.boyaa.push.lib.util.NetworkUtil;
/**
*
* @author Administrator
*
*/
public class Client {
private final int STATE_OPEN=1;//socket打開
private final int STATE_CLOSE=1<<1;//socket關閉
private final int STATE_CONNECT_START=1<<2;//開始連接server
private final int STATE_CONNECT_SUCCESS=1<<3;//連接成功
private final int STATE_CONNECT_FAILED=1<<4;//連接失敗
private final int STATE_CONNECT_WAIT=1<<5;//等待連接
private String IP="192.168.1.100";
private int PORT=60000;
private int state=STATE_CONNECT_START;
private Socket socket=null;
private OutputStream outStream=null;
private InputStream inStream=null;
private Thread conn=null;
private Thread send=null;
private Thread rec=null;
private Context context;
private ISocketResponse respListener;
private LinkedBlockingQueue<Packet> requestQueen=new LinkedBlockingQueue<Packet>();
private final Object lock=new Object();
public int send(Packet in)
{
requestQueen.add(in);
synchronized (lock)
{
lock.notifyAll();
}
return in.getId();
}
public void cancel(int reqId)
{
Iterator<Packet> mIterator=requestQueen.iterator();
while (mIterator.hasNext())
{
Packet packet=mIterator.next();
if(packet.getId()==reqId)
{
mIterator.remove();
}
}
}
public Client(Context context,ISocketResponse respListener)
{
this.context=context;
this.respListener=respListener;
}
public boolean isNeedConn()
{
return !((state==STATE_CONNECT_SUCCESS)&&(null!=send&&send.isAlive())&&(null!=rec&&rec.isAlive()));
}
public void open()
{
reconn();
}
public void open(String host,int port)
{
this.IP=host;
this.PORT=port;
reconn();
}
private long lastConnTime=0;
public synchronized void reconn()
{
if(System.currentTimeMillis()-lastConnTime<2000)
{
return;
}
lastConnTime=System.currentTimeMillis();
close();
state=STATE_OPEN;
conn=new Thread(new Conn());
conn.start();
}
public synchronized void close()
{
if(state!=STATE_CLOSE)
{
try {
if(null!=socket)
{
socket.close();
}
} catch (Exception e) {
e.printStackTrace();
}finally{
socket=null;
}
try {
if(null!=outStream)
{
outStream.close();
}
} catch (Exception e) {
e.printStackTrace();
}finally{
outStream=null;
}
try {
if(null!=inStream)
{
inStream.close();
}
} catch (Exception e) {
e.printStackTrace();
}finally{
inStream=null;
}
try {
if(null!=conn&&conn.isAlive())
{
conn.interrupt();
}
} catch (Exception e) {
e.printStackTrace();
}finally{
conn=null;
}
try {
if(null!=send&&send.isAlive())
{
send.interrupt();
}
} catch (Exception e) {
e.printStackTrace();
}finally{
send=null;
}
try {
if(null!=rec&&rec.isAlive())
{
rec.interrupt();
}
} catch (Exception e) {
e.printStackTrace();
}finally{
rec=null;
}
state=STATE_CLOSE;
}
requestQueen.clear();
}
private class Conn implements Runnable
{
public void run() {
while(state!=STATE_CLOSE)
{
try {
state=STATE_CONNECT_START;
socket=new Socket();
socket.connect(new InetSocketAddress(IP, PORT), 15*1000);
state=STATE_CONNECT_SUCCESS;
} catch (Exception e) {
e.printStackTrace();
state=STATE_CONNECT_FAILED;
}
if(state==STATE_CONNECT_SUCCESS)
{
try {
outStream=socket.getOutputStream();
inStream=socket.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
send=new Thread(new Send());
rec=new Thread(new Rec());
send.start();
rec.start();
break;
}
else
{
state=STATE_CONNECT_WAIT;
//如果有網絡沒有連接上,則定時取連接,沒有網絡則直接退出
if(NetworkUtil.isNetworkAvailable(context))
{
try {
Thread.sleep(15*1000);
} catch (InterruptedException e) {
e.printStackTrace();
break;
}
}
else
{
break;
}
}
}
}
}
private class Send implements Runnable
{
public void run() {
try {
while(state!=STATE_CLOSE&&state==STATE_CONNECT_SUCCESS&&null!=outStream)
{
Packet item;
while(null!=(item=requestQueen.poll()))
{
outStream.write(item.getPacket());
outStream.flush();
item=null;
}
synchronized (lock)
{
lock.wait();
}
}
}catch(SocketException e1)
{
e1.printStackTrace();//發送的時候出現異常,說明socket被關閉了(服務器關閉)java.net.SocketException: sendto failed: EPIPE (Broken pipe)
reconn();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
private class Rec implements Runnable
{
public void run() {
try {
while(state!=STATE_CLOSE&&state==STATE_CONNECT_SUCCESS&&null!=inStream)
{
byte[] bodyBytes=new byte[5];
int offset=0;
int length=5;
int read=0;
while((read=inStream.read(bodyBytes, offset, length))>0)
{
if(length-read==0)
{
if(null!=respListener)
{
respListener.onSocketResponse(new String(bodyBytes));
}
offset=0;
length=5;
read=0;
continue;
}
offset+=read;
length=5-offset;
}
reconn();//走到這一步,說明服務器socket斷了
break;
}
}
catch(SocketException e1)
{
e1.printStackTrace();//客戶端主動socket.close()會調用這裡 java.net.SocketException: Socket closed
}
catch (Exception e2) {
e2.printStackTrace();
}
}
}
2.使用SocketTool工具進行調試 a.創建Server.點擊TCP Server ,點擊創建,輸入端口號,點擊確定(同時要點擊啟動監聽)。 b.在android客戶端輸入IP和端口,點擊打開或者重連,socketTool便可以看見你連上的Client了 c.在客戶端輸入要發送的文字,點擊發送,在socketTool便可以看到你往server裡發送的數據了, 在socketTool裡輸入要往客戶端發送的內容,點擊發送,便可在手機客戶端裡看到Server往client發送的數據了 這樣就可以Client-Server之間進行數據對發了。
Android填坑系列:在小米系列等機型上放開定位權限後的定位請求彈框示例
背景近期因實際項目需要,在特定操作下觸發定位請求,取到用戶位置及附近位置。問題:經初步選型,最終決定接入百度定位,按照百度定位SDK Android文檔,接入過程相對順利
Android中的Service相關全面總結
1、Service的種類 按運行地點分類: 類別區別 優點缺點 應用本地服務(Local)該服務依附在主進程上, 服務依附在主進
Bluestacks安卓模擬器簡單設置使用圖解教程
Bluestacks是一個可以讓Android應用程序運行在電腦(現在包括windows系統,mac版)的一種模擬器,就是我們在電腦上也可以運行Androi
Android RecyclerView基本使用詳解
什麼是RecyclerView關於RecyclerView,是一個主要用於展示和回收View的有一個控件,在官用了一句話來概括RecyclerView 是一種通過提供有限