網路通訊Socket+Protobuf協議
阿新 • • 發佈:2019-01-08
不多說了,直接貼程式碼
大家好,如果做即時通訊,相信大家對socket也有一定的瞭解,下面主要是對socket長連線,資料封包解包,外加protobuf的例子,希望能對各位有所幫助
import java.io.BufferedReader; import java.io.File; 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.HashMap; import java.util.Map; import java.util.Set; import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.locks.ReentrantLock; import android.content.Context; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; import android.os.Message; import android.util.Log; /** * socket管理類 * @author ZengJ * */ public class IPPushManager{ public static final String tag = IPPushManager.class.getSimpleName(); private String mHostname; private int mPort; private PushListener mPushListener; public static IPPushManager pushManager; /** * 寫到伺服器的處理器 */ private ReadThread mReadThread; private HandlerThread mWriteThread; private HandlerThread mProtocaolThread; private WriteHandler mWriteHandler; public static long readWriteBytesCount = 0; /** * Socket通道 */ private Socket mSocket; private InputStream mInputStream; private OutputStream mOutputStream; private ReentrantLock mSockConnectionReentrantLock = new ReentrantLock(); private Context mContext; private Set<ISocketClient> mListener = new CopyOnWriteArraySet<ISocketClient>(); // 儲存每次上傳器的物件 private HashMap<Long, UploadFile> mMapUploadFile = new HashMap<Long, UploadFile>(); // 儲存每次下載器的物件 private HashMap<Integer, DownloadFile> mMapDownLoadFile = new HashMap<Integer, DownloadFile>(); private IPPushManager(String hostName, int port) { mHostname = hostName; mPort = port; } public static void init(String hostName, int port) { if (pushManager == null) { pushManager = new IPPushManager(hostName, port); } } public static IPPushManager getInstance() { if (pushManager == null) { throw new RuntimeException("before call init()"); } return pushManager; } public void addListener(ISocketClient listener) { if (listener != null) { mListener.add(listener); } } public void removeListener(ISocketClient listener) { if (listener != null) { mListener.remove(listener); } } /** * 傳送訊息 * * @Title: send * @Description: TODO * @return: void */ public void send(byte[] request) { if (mWriteHandler != null) { mWriteHandler.sendMessage(mWriteHandler.obtainMessage(0, request)); } } public void setPushListener(PushListener pushListener) { mPushListener = pushListener; } /** * 建立連線 * * @Title: connect * @Description: TODO * @return: void */ public void connect(final OnConnectListener listener) { new Thread() { public void run() { mSockConnectionReentrantLock.lock(); try { if (isConnected()) { return; } // dissConnect(); InetSocketAddress addr = new InetSocketAddress(mHostname, mPort); mSocket = new Socket(); mSocket.connect(addr, 10 * 1000); if (mSocket.isConnected()) { mSocket.setKeepAlive(true); // 長連線 mSocket.setTcpNoDelay(true);// 資料不作緩衝,立即傳送 mSocket.setSoLinger(true, 0);// socket關閉時,立即釋放資源 mInputStream = mSocket.getInputStream(); mOutputStream = mSocket.getOutputStream(); // 初始化協議處理器 mProtocaolThread = new HandlerThread( "IPPush ProtocaolController"); mProtocaolThread.start(); mReadThread = new ReadThread(); mReadThread.setName("IPPush ReadHandlerThread"); mReadThread.start(); mWriteThread = new HandlerThread( "IPPush WriteHandlerThread"); mWriteThread.start(); mWriteHandler = new WriteHandler( mWriteThread.getLooper()); if (listener != null) { listener.onConnectSuccess(IPPushManager.this); } } else { // 連線失敗 if (listener != null) { listener.onConnectFail(new SocketException("連線失敗")); } } } catch (Exception e) { // 連線失敗 if (listener != null) { listener.onConnectFail(e); } dissConnect(); } finally { mSockConnectionReentrantLock.unlock(); } }; }.start(); } /** * 通道是否開啟 * * @Title: isOpen * @Description: TODO * @return * @return: boolean */ public boolean isConnected() { try { return mSocket != null && mSocket.isConnected() && !mSocket.isInputShutdown() && !mSocket.isOutputShutdown(); } catch (Exception e) { return false; } } public void onPush() { if (mPushListener != null) { mPushListener.onPush(); } } /** * 斷開連線 * * @Title: dissConnect * @Description: TODO * @return: void */ public void dissConnect() { try { if (mInputStream != null) { mInputStream.close(); mInputStream = null; } if (mOutputStream != null) { mOutputStream.close(); mOutputStream = null; } if (mSocket != null) { mSocket.close(); mSocket = null; } if (mWriteHandler != null) { mWriteHandler.sendEmptyMessage(-1); mWriteHandler = null; } readWriteBytesCount = 0; } catch (Exception e) { } } private class WriteHandler extends Handler { public WriteHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { if (msg.what == -1) { getLooper().quit(); return; } if (msg.obj != null && msg.obj instanceof byte[]) { if (!isConnected()) { // 伺服器已斷開連線 return; } try { byte[] buffer = (byte[]) msg.obj; readWriteBytesCount += buffer.length; mOutputStream.write(buffer); mOutputStream.flush(); Log.d("IPPush", "-----------------------------"); } catch (IOException e) { e.printStackTrace(); dissConnect(); LogHelper.e(tag + "_WriteHandler發生了IOException", e.getMessage()); } } super.handleMessage(msg); } } private class ReadThread extends Thread { public ReadThread() { } private boolean readData(byte[] data) { int length = data.length; long firstTime = 0; int i = 0; while (true) { if (firstTime == 0) { firstTime = System.currentTimeMillis(); } else { if (System.currentTimeMillis() - firstTime > 3000) { return false; } } try { int readLength = 0; if ((readLength = mInputStream.read(data, i, length - i)) == length - i) { // 讀取成功,資料在data裡 Log.d("data", "" + data.length); return true; } else { i += readLength; } } catch (IOException e) { e.printStackTrace(); LogHelper.e(tag + "_Error", e.getMessage()); return false; } } } @Override public void run() {//資料讀取這一塊就根據具體協議來定 try { StringBuffer stringBuffer = new StringBuffer(); Log.d("stringBuffer", "" + stringBuffer.length()); String line = null; final byte[] successHeader = new byte[3]; while (isConnected()) { byte[] header = new byte[4]; if (readData(header)) { int length = Util.toInt(header); byte[] data = new byte[length]; if (readData(data)) { int i = mListener.size(); for (ISocketClient listener : mListener) { ProtobufHandler.getInstance(mContext).read( listener, mContext, data); } } } /* * if (mInputStream.read(header) == 3) { int length = * mInputStream.read(); Log.d("length", "" + length); byte[] * data = new byte[length]; long firstTime = 0; int i = 0; * while(true){ if(firstTime == 0){ firstTime = * System.currentTimeMillis(); } else{ * if(System.currentTimeMillis() - firstTime > 3000){ break; * } } if ((i = mInputStream.read(data, i, length - i)) == * length - i) { // 讀取成功,資料在data裡 Log.d("data", "" + * data.length); // for (int i = 0; i < data.length; i++) { * // Log.d("data"+i, "" + data[i]); // } * * for(ISocketClient listener : mListener){ * ProtobufHandler.getInstance(mContext).read(listener, * mContext, data); } break; } else { * * } } * * } */ /* * try { Thread.sleep(2000); } catch (InterruptedException * e) { } */ } // while (isConnected()) { // // // byte[] recvMsg2 = recvMsg(mInputStream); // Log.d("recvMsg2", "" + recvMsg2.length); // byte[] readByte = Bytes.readByte(recvMsg2); // Log.d("readByte", "" + readByte.length); // ProtobufHandler.getInstance(mContext).read(mListener1, // mContext, readByte); // try { // Thread.sleep(5000); // } catch (InterruptedException e) { // } // } } catch (Exception e) { e.printStackTrace(); LogHelper.e(tag + "_ReadThread發生了IOException", e.getMessage()); } finally { // dissConnect(); } // 伺服器已斷開連線 } } /** * 接收server的資訊 * * @return * @throws SmsClientException * @author fisher */ public byte[] recvMsg(InputStream inpustream) { try { byte len[] = new byte[1024]; int count = inpustream.read(len); byte[] temp = new byte[count]; for (int i = 0; i < count; i++) { temp[i] = len[i]; } return temp; } catch (Exception e) { e.printStackTrace(); } return null; } /** * 上傳檔案 * * @return 返回本次請求的flag標識 * @throws ConnectionException */ public long upLoadFile(String url, InputStream is, String filename, Map<String, String> map, long flag, UploadFileCallback callback) throws Exception { UploadFile upLoadFile = new UploadFile(mContext, is, filename, url, map, callback, flag); mMapUploadFile.put(flag, upLoadFile); new Thread(upLoadFile).start(); return flag; } /** * 下載檔案 * * @param url * @return -1請求失敗 * @throws ConnectionException */ public int downLoadFile(Context context, String url, int flag, DownloadFileCallback callback) throws Exception { if (CommonFuncation.isEmptyOrNullStr(url)) { return -1; } String filename = url.substring(url.lastIndexOf("/") + 1, url.length()); return downLoadFile(context, url, Config.cacheAudioPath, filename, flag, callback); } /** * 下載檔案 * * @param url * @param dir * @param filename * @return * @throws ConnectionException */ public int downLoadFile(Context context, String url, String dir, String filename, int flag, DownloadFileCallback callback) throws Exception { mMapDownLoadFile.put(flag, null); File file = new File(dir, filename); DownloadFile downLoadFile = new DownloadFile(context, callback, url, filename, file.getAbsolutePath(), flag, file.exists()); new Thread(downLoadFile).start(); return flag; } // 關閉下載 public void closeDownLoadFile(int flag) { if (mMapDownLoadFile.containsKey(flag)) { mMapDownLoadFile.get(flag).close(); mMapDownLoadFile.remove(flag); } } public static interface OnConnectListener { public void onConnectSuccess(IPPushManager manager); public void onConnectFail(Exception e); } public static interface PushListener { /** * 有推送內容到達 * * @Title: onPush * @Description: TODO * @return: void */ public void onPush(); } }
import java.util.HashMap; import java.util.List; import java.util.Stack; import android.app.Activity; import android.app.ActivityManager; import android.app.AlarmManager; import android.app.PendingIntent; import android.app.Service; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.os.Binder; import android.os.IBinder; import android.os.SystemClock; import android.text.TextUtils; import android.util.Log; /** * * @author ZengJ * @data 2014-04-24 10:20:15 * @version 1.0.0 * * */ public class IPPushService extends Service { public final static String tag = IPPushService.class.getSimpleName(); public final static String ACTION_HEART = "com.changyou.rc_sdk.socket。heart"; public final static String ACTION_SEND = "com.changyou.rc_sdk.socket.send"; public final static String PARAMS_SEND = "data"; public final static String NETWORK = ConnectivityManager.CONNECTIVITY_ACTION; public final static int REQUEST_CODE_HEART_ALARM = 0x99; private String mHost = ""; private int mPort = 0; private static final int NET_CHECK_HEART_TIME = 25 * 1000; private static final int WAP_CHECK_HEART_TIME = 25 * 1000; public static boolean isOpen = false; public static int sHeartCount = 0; private int mHeartCheckTime = NET_CHECK_HEART_TIME;// 25s檢測一次心跳狀態 private IPPushServiceBinder mIPPushServiceBinder = new IPPushServiceBinder(); private IPPushManager mIPPushManager; private IPPushHeartReceiver mIPPushHeartReceiver; HashMap<Type, ISocketClient> mMaps; public void registerListener(Type type, ISocketClient listener) { } /** * 啟動IPPush服務 * * @Title: startIPPushService * @Description: TODO * @param context * @return: void * * */ public static synchronized void startIPPushService(Context context, String host, int port) { if (isOpen) { return; } if (isServiceRunning(context)) { return; } isOpen = true; if (context == null) { return; } try { context.startService(new Intent(context, IPPushService.class) .putExtra("host", host).putExtra("port", port)); } catch (Exception e) { } } /** * 重啟IPPush服務 * * @Title: startIPPushService * @Description: TODO * @param context * @return: void */ public static synchronized void restartIPPushService(Context context, String host, int port) { if (isOpen) { return; } if (context == null) { return; } closeIPPushService(context); startIPPushService(context, host, port); } /** * 關閉IPPush服務 * * @Title: closeIPPushService * @Description: TODO * @param context * @return: void */ public static synchronized void closeIPPushService(Context context) { if (context == null) { return; } try { context.stopService(new Intent(context, IPPushService.class)); } catch (Exception e) { } } /** * 用來判斷服務是否執行. * * @param context * @param className * 判斷的服務名字:包名+類名 * @return true 在執行, false 不在執行 */ public static boolean isServiceRunning(Context context) { boolean isRunning = false; ActivityManager activityManager = (ActivityManager) context .getSystemService(Context.ACTIVITY_SERVICE); List<ActivityManager.RunningServiceInfo> serviceList = activityManager .getRunningServices(Integer.MAX_VALUE); if (!(serviceList.size() > 0)) { return false; } for (int i = 0; i < serviceList.size(); i++) { if (serviceList.get(i).service.getClassName().equals( IPPushService.class.getName()) == true) { isRunning = true; break; } } return isRunning; } @Override public void onCreate() { super.onCreate(); mIPPushHeartReceiver = new IPPushHeartReceiver(); IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(ACTION_HEART); intentFilter.addAction(ACTION_SEND); intentFilter.addAction(NETWORK); registerReceiver(mIPPushHeartReceiver, intentFilter); } private class IPPushHeartReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (ACTION_HEART.equals(action)) { LogHelper.d(tag + "_心跳中", "(" + sHeartCount++ + ")..."); if (mIPPushManager == null || !mIPPushManager.isConnected()) { // 發起註冊並連線的任務 LogHelper.d(tag + "_connect", " 失去連線"); connect(); } else { // 發出心跳包 RCMessage.Builder builder = Params.sendHeartbeat(); byte[] writeHeart = ProtobufHandler.getInstance(context) .writeHeart(builder, IPPushService.this); if (writeHeart != null) { mIPPushManager.send(writeHeart); } // RCMessage.Builder builder = RCMessage.newBuilder(); // HeatBit.Builder heatbit = HeatBit.newBuilder(); // heatbit.setUid(ChangYouManager.getInstance().getUid()); // heatbit.setGameKey(ChangYouManager.getInstance().getUid()); // heatbit.setDistrict(ChangYouManager.getInstance().getUid()); // heatbit.setServerid(ChangYouManager.getInstance().getUid()); // heatbit.setNickname(ChangYouManager.getInstance().getUid()); // builder.setHeatBit(heatbit); // builder.setUri(Type.HEAT_BIT); // RCMessage message = builder.build(); // byte[] byteArray = message.toByteArray(); // byte[] setByteLength = Bytes.setByteLength(byteArray); // mIPPushManager.send(setByteLength); // CommonFuncation.log("write", byteArray.length); // CommonFuncation.log("setByteLength", // setByteLength.length); LogHelper.d(tag + "_HEART", "傳送客戶端心跳請求"); // 設定下次心跳時間 setCheckHeartTime(NetworkUtil.getNetworkType(context)); setHeartAlarm(); } } else if (ACTION_SEND.equals(action)) { if (mIPPushManager != null && mIPPushManager.isConnected()) { byte[] data = intent.getByteArrayExtra(PARAMS_SEND); if (data != null) { mIPPushManager.send(data); } } } else if (NETWORK.equals(action)) { Log.d("mark", "網路狀態已經改變"); ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo info = connectivityManager.getActiveNetworkInfo(); if (info != null && info.isAvailable()) { String name = info.getTypeName(); Log.d("mark", "當前網路名稱:" + name); connect(); } else { Log.d("mark", "沒有可用網路"); connect(); } } } } @Override @Deprecated public void onStart(Intent intent, int startId) { super.onStart(intent, startId); if (intent == null) { stopSelf(); return; } // 獲取啟動引數 mHost = intent.getStringExtra("host"); mPort = intent.getIntExtra("port", -1); LogHelper.d(tag+"_獲取啟動引數", "獲取啟動引數"); LogHelper.d(tag+"_Host:", mHost); LogHelper.d(tag+"_Port:", mPort); if (TextUtils.isEmpty(mHost) || mPort <= 0) { LogHelper.d("獲取啟動引數失敗", "獲取啟動引數失敗"); stopSelf(); return; } else { connect(); } } private void setHeartAlarm() { setCheckHeartTime(NetworkUtil.getNetworkType(this)); LogHelper.d(tag+"_設定心跳監聽:", mHeartCheckTime); // 註冊一個鬧鐘 心跳這塊ELAPSED_REALTIME 這個休眠後是不會發送心跳了,建議加上cpu休眠喚醒, //但是比較耗電,程式碼會在最下面,諸君最好是在服務或者application裡面新增 AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); Intent i = new Intent(ACTION_HEART); // PendingIntent pendingIntent=PendingIntent.getBroadcast(this, 0, i, // PendingIntent.FLAG_UPDATE_CURRENT); // long elapsedRealtime = SystemClock.elapsedRealtime(); // alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, // elapsedRealtime, 25*1000, pendingIntent); PendingIntent pendingIntent = PendingIntent.getBroadcast(this, REQUEST_CODE_HEART_ALARM, i, PendingIntent.FLAG_CANCEL_CURRENT); // 如果系統中已存在該鬧鐘,先取消 // alarmManager.cancel(pendingIntent); // 設定鬧鐘時間(伺服器返回的時間是以秒為單位) long triggerAtTime = SystemClock.elapsedRealtime() + 25 * 1000; alarmManager.set(AlarmManager.ELAPSED_REALTIME, triggerAtTime, pendingIntent); LogHelper.d(tag+"_設定心跳監聽1:", mHeartCheckTime); } /** * 連線IPPush服務 * * @Title: connect * @Description: TODO * @return: void */ private void connect() { if (!NetworkUtil.isNetworkConnected(this)) { LogHelper.d(tag+"_connect", " 網路連線不可用"); return; } if (mIPPushManager == null) { mIPPushManager = IPPushManager.getInstance(); mIPPushManager.setPushListener(new PushListener() { @Override public void onPush() { LogHelper.d(tag+"_onPush", "true"); } }); } if (!mIPPushManager.isConnected()) { LogHelper.d(tag+"_connect", " 開始連線"); mIPPushManager.connect(new OnConnectListener() { @Override public void onConnectSuccess(IPPushManager manager) { LogHelper.d(tag+"_connect", " 連線成功"); // // 發起註冊請求 // RCMessage.Builder builder=RCMessage.newBuilder(); // HeatBit.Builder heatbit=HeatBit.newBuilder(); // heatbit.setUid(ChangYouManager.getInstance().getUid()); // heatbit.setGameKey(ChangYouManager.getInstance().getUid()); // heatbit.setDistrict(ChangYouManager.getInstance().getUid()); // heatbit.setServerid(ChangYouManager.getInstance().getUid()); // heatbit.setNickname(ChangYouManager.getInstance().getUid()); // builder.setHeatBit(heatbit); // builder.setUri(Type.HEAT_BIT); // byte[] write = // ProtobufHandler.getInstance().write(IPPushService.this, // builder); // byte[] setByteLength = Bytes.setByteLength(write); // CommonFuncation.log("write", write.length); // CommonFuncation.log("setByteLength", // setByteLength.length); // mIPPushManager.send(setByteLength); // 傳送心跳監聽 sendBroadcast(new Intent(ACTION_HEART)); } @Override public void onConnectFail(Exception e) { // 稍後重試 LogHelper.d(tag+"_connect", " 連線失敗"); } }); } } @Override public IBinder onBind(Intent intent) { return mIPPushServiceBinder; } @Override public void onDestroy() { super.onDestroy(); if (mIPPushHeartReceiver != null) { unregisterReceiver(mIPPushHeartReceiver); } if (mIPPushManager != null) { // mIPPushManager.dissConnect(); } isOpen = false; } // public void onEventMainThread(NetworkChangeEvent event) { // CommonFuncation.log("網路狀態發生變化:" + event.type); // setCheckHeartTime(event.type); // sendBroadcast(new Intent(ACTION_HEART)); // } /** * 判斷網路狀態 * * @Title: getAPNType * @Description: TODO * @param context * @return * @return: int */ public void setCheckHeartTime(int networkType) { if (networkType == 0) { mHeartCheckTime = NET_CHECK_HEART_TIME; } else if (networkType == 1) { mHeartCheckTime = NET_CHECK_HEART_TIME; } else if (networkType == 2) { mHeartCheckTime = WAP_CHECK_HEART_TIME; } else if (networkType == 3) { mHeartCheckTime = NET_CHECK_HEART_TIME; } else if (networkType == 4) { mHeartCheckTime = NET_CHECK_HEART_TIME; } else { mHeartCheckTime = WAP_CHECK_HEART_TIME; } } class IPPushServiceBinder extends Binder { public IPPushService getService() { return IPPushService.this; } } public static interface IIPPushServiceBindListener { public void onServiceDisconnected(); public void onServiceConnected(IPPushService service); } }
import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import android.content.Context; import android.content.Intent; /** * * @author ZengJ * @data 2014-04-28 14:20:23 */ public class ProtobufHandler { public static final String tag = ProtobufHandler.class.getSimpleName(); private long reqNum; private HashMap<Long, Long> mProtoMap; private List<ListenerHolder> mListnerList; private static ProtobufHandler protobufHandler; private ProtobufHandler(Context context) { reqNum = 0; mProtoMap = new HashMap<Long, Long>(); mListnerList = new ArrayList<ListenerHolder>(); } public static ProtobufHandler getInstance(Context context) { if (protobufHandler == null) { protobufHandler = new ProtobufHandler(context); } return protobufHandler; } /** * 客戶端資料請求 * * @param builder * @return */ public void write(Context context, RCMessage.Builder builder, IProtobufListener protoHolder) { builder.setMsgSeqno(++reqNum); RCMessage message = builder.build(); byte[] byteArray = message.toByteArray(); byte[] setByteLength = Bytes.setByteLength(byteArray); context.sendBroadcast(new Intent(IPPushService.ACTION_SEND).putExtra( IPPushService.PARAMS_SEND, setByteLength)); LogHelper.d(tag + "_byteArray", byteArray.length); LogHelper.d(tag + "_setByteLength", setByteLength.length); ProtoHolder holder = new ProtoHolder(reqNum, protoHolder); mProtoMap.put(reqNum, reqNum); } /** * 客戶端心跳 * * @param builder * @return */ public byte[] writeHeart(RCMessage.Builder builder, IProtobufListener protoHolder) { builder.setMsgSeqno(++reqNum); RCMessage message = builder.build(); byte[] byteArray = message.toByteArray(); byte[] setByteLength = Bytes.setByteLength(byteArray); LogHelper.d(tag + "_byteArray", byteArray.length); LogHelper.d(tag + "_setByteLength", setByteLength.length); ProtoHolder holder = new ProtoHolder(reqNum, protoHolder); mProtoMap.put(reqNum, reqNum); return setByteLength; } /** * 從伺服器讀取資料 * * @param bytes */ public void read(ISocketClient iSocketClient, Context context, byte[] bytes) { try { if (bytes == null) { return; } RCMessage message = RCMessage.parseFrom(bytes); FilterUtil.getInstance().filterReceiveSocket(iSocketClient, context, message); // if (message.hasMsgSeqno() == false) { // RCMessage.Type type = message.getUri(); // for (ListenerHolder listenerHolder : mListnerList) { // if (listenerHolder.mType == type) // listenerHolder.mProtobufListener.handleProto(message); // } // return; // } } catch (InvalidProtocolBufferException e) { e.printStackTrace(); } } public void RegisterRecListener(RCMessage.Type type, IProtobufListener protoListener) { mListnerList.add(new ListenerHolder(type, protoListener)); } public void UnregisterRecListener(IProtobufListener protoListener) { for (Iterator<ListenerHolder> it = mListnerList.iterator(); it .hasNext();) { ListenerHolder listenerHolder = it.next(); if (listenerHolder == protoListener) it.remove(); } } class ListenerHolder { public RCMessage.Type mType; public IProtobufListener mProtobufListener; public ListenerHolder(RCMessage.Type type, IProtobufListener protobufListener) { mType = type; mProtobufListener = protobufListener; } } class ProtoHolder { public long seq; public IProtobufListener protoHolder; public ProtoTimeoutRunnable runnable; public ProtoHolder(long seq, IProtobufListener proListener) { this.seq = seq; this.protoHolder = proListener; this.runnable = new ProtoTimeoutRunnable(this.seq); } } class ProtoTimeoutRunnable implements Runnable { public long seq; public ProtoTimeoutRunnable(long seq) { this.seq = seq; } @Override public void run() { // 這裡應該是超時 if (mProtoMap.containsKey(seq)) { // ProtoHolder protoHoler = mProtoMap.remove(this.seq); // protoHoler.protoHandler.handleProtoTimeout(); } } } }
public void acquireWakeLock(){
if(wakeLock == null){
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKE_TAG);
wakeLock.acquire();
}
}
public void releaseWakeLock(){
if(wakeLock != null && wakeLock.isHeld()){
wakeLock.release();
wakeLock = null;
}
}
在oncreate新增,銷燬的時候釋放,親,喚醒鎖記得加許可權,也可以用timer+喚醒鎖,先到這了有時間在寫,多多關注,精彩在後續