From 9e1097ca3eff1c25df69990fc1098144c7cbcb56 Mon Sep 17 00:00:00 2001
From: yy1717 <fctom1215@outlook.com>
Date: 星期一, 30 十二月 2019 17:38:01 +0800
Subject: [PATCH] Merge branch 'master' of https://gitee.com/endian11/DriveJudge

---
 app/src/main/java/safeluck/drive/evaluation/bean/DriveExamProtocol.java            |  132 ++++++
 app/src/main/java/safeluck/drive/evaluation/im/handler/IMessageHandler.java        |   11 
 app/src/main/java/safeluck/drive/evaluation/cEventCenter/PooledObject.java         |   15 
 app/src/main/java/safeluck/drive/evaluation/im/handler/AbstractMessageHandler.java |   15 
 app/src/main/java/safeluck/drive/evaluation/fragment/TrainFragment.java            |    2 
 app/src/main/java/safeluck/drive/evaluation/util/CThreadPoolExecutor.java          |  332 +++++++++++++++++
 app/src/main/java/safeluck/drive/evaluation/im/MessageProcessor.java               |   48 ++
 app/src/main/java/safeluck/drive/evaluation/im/IMSConnectStatusListener.java       |   31 +
 app/src/main/java/safeluck/drive/evaluation/im/IMSEventListener.java               |   76 ++++
 app/src/main/java/safeluck/drive/evaluation/cEventCenter/CEvent.java               |   70 +++
 app/src/main/java/safeluck/drive/evaluation/im/IMessageProcessor.java              |   12 
 app/src/main/java/safeluck/drive/evaluation/cEventCenter/ObjectPool.java           |   55 ++
 app/src/main/java/safeluck/drive/evaluation/bean/RegisterMessage.java              |   27 +
 app/src/main/java/safeluck/drive/evaluation/im/IMSClientFactory.java               |   16 
 app/src/main/java/safeluck/drive/evaluation/DB/WorkRoomDataBase.java               |   12 
 app/src/main/java/safeluck/drive/evaluation/bean/KeepaliveMessage.java             |   22 +
 app/src/main/java/safeluck/drive/evaluation/bean/GainStuMessage.java               |   26 +
 app/src/main/java/safeluck/drive/evaluation/DB/Student.java                        |   10 
 app/src/main/java/safeluck/drive/evaluation/fragment/TcpFragment.java              |   48 +
 app/src/main/java/safeluck/drive/evaluation/bean/StartExamMessage.java             |   25 +
 app/src/main/java/safeluck/drive/evaluation/im/IMSClientBootstrap.java             |  109 +++++
 app/build.gradle                                                                   |    1 
 22 files changed, 1,081 insertions(+), 14 deletions(-)

diff --git a/app/build.gradle b/app/build.gradle
index 534a8e5..65e4132 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -55,4 +55,5 @@
     implementation project(path: ':lib')
     implementation 'com.google.code.gson:gson:2.8.6'
     implementation 'com.facebook.stetho:stetho:1.5.0'
+    implementation project(path: ':im_lib')
 }
diff --git a/app/src/main/java/safeluck/drive/evaluation/DB/Student.java b/app/src/main/java/safeluck/drive/evaluation/DB/Student.java
index 7bdd242..f44e818 100644
--- a/app/src/main/java/safeluck/drive/evaluation/DB/Student.java
+++ b/app/src/main/java/safeluck/drive/evaluation/DB/Student.java
@@ -30,6 +30,16 @@
     @ColumnInfo(name = "sex")
     private int sex;
 
+    public long getBegin_time() {
+        return begin_time;
+    }
+
+    public void setBegin_time(long begin_time) {
+        this.begin_time = begin_time;
+    }
+
+    private long begin_time;
+
     public Student(long stu_id, @NonNull String name, String ID, int sex) {
         this.stu_id = stu_id;
         this.name = name;
diff --git a/app/src/main/java/safeluck/drive/evaluation/DB/WorkRoomDataBase.java b/app/src/main/java/safeluck/drive/evaluation/DB/WorkRoomDataBase.java
index 97aff86..5c0fd1f 100644
--- a/app/src/main/java/safeluck/drive/evaluation/DB/WorkRoomDataBase.java
+++ b/app/src/main/java/safeluck/drive/evaluation/DB/WorkRoomDataBase.java
@@ -7,6 +7,7 @@
 import androidx.room.Database;
 import androidx.room.Room;
 import androidx.room.RoomDatabase;
+import androidx.room.migration.Migration;
 import androidx.sqlite.db.SupportSQLiteDatabase;
 import androidx.work.OneTimeWorkRequest;
 import androidx.work.WorkManager;
@@ -31,7 +32,7 @@
  * 閭锛�632393724@qq.com
  * All Rights Saved! Chongqing AnYun Tech co. LTD
  */
-@Database(entities = {Student.class, CriteriaForI.class, FailedProj.class, CriteriaForII.class},version = 1,exportSchema = false)
+@Database(entities = {Student.class, CriteriaForI.class, FailedProj.class, CriteriaForII.class},version = 2,exportSchema = false)
 public abstract class WorkRoomDataBase extends RoomDatabase {
     private static final String TAG = "WorkRoomDataBase";
     public abstract StudentDao getstudentDao();
@@ -46,6 +47,14 @@
     private static final int NUMBER_OF_THREADS = 4;
 
     public static final ExecutorService dataBaseWriteExecutor = Executors.newFixedThreadPool(NUMBER_OF_THREADS);
+    static Migration migration = new Migration(1,2) {
+        @Override
+        public void migrate(@NonNull SupportSQLiteDatabase database) {
+            database.execSQL("alter table student_table ADD  COLUMN begin_time INTEGER NOT NULL DEFAULT 0");
+        }
+    };
+private static final Migration[] ALL_MIGRATIONS = new Migration[]{migration};
+
 
      public static WorkRoomDataBase getWorkRoomDataBase(final Context mContext){
          Log.i(TAG, "getWorkRoomDataBase");
@@ -54,6 +63,7 @@
                 if (workRoomDataBase == null){
                     Log.i(TAG, "getWorkRoomDataBase==null ");
                     workRoomDataBase = Room.databaseBuilder(mContext.getApplicationContext(),WorkRoomDataBase.class,"work_database")
+                            .addMigrations(ALL_MIGRATIONS)
                             .addCallback(new Callback() {
                                 @Override
                                 public void onCreate(@NonNull SupportSQLiteDatabase db) {
diff --git a/app/src/main/java/safeluck/drive/evaluation/bean/DriveExamProtocol.java b/app/src/main/java/safeluck/drive/evaluation/bean/DriveExamProtocol.java
new file mode 100644
index 0000000..06af76c
--- /dev/null
+++ b/app/src/main/java/safeluck/drive/evaluation/bean/DriveExamProtocol.java
@@ -0,0 +1,132 @@
+package safeluck.drive.evaluation.bean;
+
+import android.util.Log;
+
+import com.anyun.im_lib.util.ByteUtil;
+
+/**
+ * MyApplication2
+ * Created by lzw on 2019/12/17. 15:39:23
+ * 閭锛�632393724@qq.com
+ * All Rights Saved! Chongqing AnYun Tech co. LTD
+ */
+public abstract class DriveExamProtocol {
+
+    private static final String TAG = "DriveExamProtocol";
+    /***========================
+                娑堟伅缁撴瀯琛�
+    鏍囪瘑浣�	娑堟伅澶�	娑堟伅浣�	鏍¢獙鐮�	鏍囪瘑浣�
+     0x7E                                                       0x7E
+    ======================**/
+   // 鏍囪瘑浣�(瀛楄妭娴佸紑濮嬶級
+    private byte MESSAGE_HEAD = 0x7e;
+    //鏍囪瘑浣嶏紙瀛楄妭娴佺粨鏉燂級
+    private byte MESSAGE_TAIL = 0x7e;
+
+    //鏍¢獙鐮佹寚浠庢秷鎭ご寮�濮嬶紝鍚屽悗涓�瀛楄妭寮傛垨锛岀洿鍒版牎楠岀爜鍓嶄竴涓瓧鑺傦紝鍗犵敤涓�涓瓧鑺�
+//鏍¢獙鐮�  鍏堟殏鏃跺啓姝� todo
+    private byte checkCode = 0x78;
+
+
+/***===========浠ヤ笅鏄秷鎭ご=============***/
+    //鍗忚鐗堟湰鍙�	BYTE	235锛屽浐瀹�
+    private short protocol_version = 235;
+//娑堟伅ID
+    private short msg_id;
+
+
+   /**銆�娑堟伅浣撳睘鎬ф牸寮忕粨鏋勮〃
+15	14	13   |	12	11	10	| 9	8	7	6	5	4	3	2	1	0
+    淇濈暀	      鏁版嵁鍔犲瘑鏂瑰紡     	娑堟伅浣撻暱搴�
+**/
+    //娑堟伅浣撳睘鎬�
+    private short msg_property  =2;
+
+    /**
+       * 缁堢鎵嬫満鍙� 瀛楃涓查暱搴﹀繀椤讳负16
+    **/
+    private String phoneOnTerminal = "0008618513021245";
+
+    /**
+     *
+     * 13	娑堟伅娴佹按鍙�	WORD	鎸夊彂閫侀『搴忎粠0寮�濮嬪惊鐜疮鍔�
+     *
+     */
+    public static short msg_serial_num=0;
+
+    //15	棰勭暀	BYTE	棰勭暀
+    private byte reserve = 0x00;
+    /***===========娑堟伅澶寸粨鏉�=============***/
+
+    /**
+     * 娑堟伅浣� 闇�瑕佸瓙绫诲疄鐜�
+     */
+    protected abstract byte[] createMessageBody();
+
+    /**
+     * 鏋勯�犲嚱鏁�
+     * @param msg_id 娑堟伅ID
+     */
+    public DriveExamProtocol(short msg_id) {
+        this.msg_id = msg_id;
+    }
+
+    /**
+     * 娑堟伅杞负byte鏁扮粍 7E......7E
+     * @return
+     */
+    public byte[] toBytes(){
+        byte[] desBytes = new byte[1+16+2+1+1];
+        int pos = 0;
+
+
+        //鏍囪瘑浣�
+        desBytes[pos] = MESSAGE_HEAD;
+        pos++;
+
+
+        //鍗忚鐗堟湰鍙�
+        byte[] protoVersion = ByteUtil.shortGetByte(protocol_version);
+        System.arraycopy(protoVersion,0,desBytes,pos,protoVersion.length);
+        pos +=protoVersion.length;
+
+        //娑堟伅ID
+        byte[] msgIdBytes = ByteUtil.shortGetBytes(msg_id);
+        System.arraycopy(msgIdBytes,0,desBytes,pos,msgIdBytes.length);
+        pos+=msgIdBytes.length;
+
+        //娑堟伅浣撳睘鎬�
+        byte[] msg_pro_bytes = ByteUtil.shortGetBytes(msg_property);
+        System.arraycopy(msg_pro_bytes,0,desBytes,pos,msg_pro_bytes.length);
+        pos+=msg_pro_bytes.length;
+        //缁堢鎵嬫満鍙�
+        byte[] phoneBytes = ByteUtil.str2Bcd(phoneOnTerminal);
+        System.arraycopy(phoneBytes,0,desBytes,pos,phoneBytes.length);
+        pos+=phoneBytes.length;
+        //娑堟伅娴佹按鍙�
+        byte[] msg_serialNum = ByteUtil.shortGetBytes(msg_serial_num++);
+        System.arraycopy(msg_serialNum,0,desBytes,pos,msg_serialNum.length);
+        pos+=msg_serialNum.length;
+        //淇濈暀byte
+        desBytes[pos] = reserve;
+        pos++;
+
+        //娑堟伅浣�
+        byte[] messageBodyBytes = createMessageBody();
+        System.arraycopy(messageBodyBytes,0,desBytes,pos,messageBodyBytes.length);
+        pos+=messageBodyBytes.length;
+
+        //鏍¢獙鐮�
+        // TODO: 2019/12/18 鏍¢獙鐮侀渶瑕佽绠�   杩樻湁杞箟闇�瑕佸鐞�
+        desBytes[pos] = checkCode;
+        pos++;
+        //鏈熬缁撴潫鏍囪瘑浣�
+        desBytes[pos] = MESSAGE_TAIL;
+
+        Log.i(TAG, "鍖呴暱搴�="+(pos+1));
+        Log.i(TAG, "鍖呭唴瀹�: "+ByteUtil.byte2HexStr(desBytes));
+
+        return desBytes;
+    }
+
+}
diff --git a/app/src/main/java/safeluck/drive/evaluation/bean/GainStuMessage.java b/app/src/main/java/safeluck/drive/evaluation/bean/GainStuMessage.java
new file mode 100644
index 0000000..74960fd
--- /dev/null
+++ b/app/src/main/java/safeluck/drive/evaluation/bean/GainStuMessage.java
@@ -0,0 +1,26 @@
+package safeluck.drive.evaluation.bean;
+
+/**
+ * 鑾峰彇瀛﹀憳淇℃伅娑堟伅锛堝彂閫佽韩浠借瘉ID涓婂幓缁欏钩鍙帮級
+ * MyApplication2
+ * Created by lzw on 2019/12/19. 18:26:35
+ * 閭锛�632393724@qq.com
+ * All Rights Saved! Chongqing AnYun Tech co. LTD
+ */
+public class GainStuMessage extends DriveExamProtocol {
+    // TODO: 2019/12/19
+    /**
+     * 鏋勯�犲嚱鏁�
+     *
+     * @param msg_id 娑堟伅ID
+     */
+    public GainStuMessage(short msg_id) {
+        super(msg_id);
+    }
+
+    @Override
+    protected byte[] createMessageBody() {
+
+        return new byte[0];
+    }
+}
diff --git a/app/src/main/java/safeluck/drive/evaluation/bean/KeepaliveMessage.java b/app/src/main/java/safeluck/drive/evaluation/bean/KeepaliveMessage.java
new file mode 100644
index 0000000..f04f4e1
--- /dev/null
+++ b/app/src/main/java/safeluck/drive/evaluation/bean/KeepaliveMessage.java
@@ -0,0 +1,22 @@
+package safeluck.drive.evaluation.bean;
+
+/**
+ * 蹇冭烦娑堟伅
+ * MyApplication2
+ * Created by lzw on 2019/12/19. 18:24:47
+ * 閭锛�632393724@qq.com
+ * All Rights Saved! Chongqing AnYun Tech co. LTD
+ */
+public class KeepaliveMessage extends DriveExamProtocol {
+
+// TODO: 2019/12/19  
+
+    public KeepaliveMessage(short msg_id) {
+        super(msg_id);
+    }
+
+    @Override
+    protected byte[] createMessageBody() {
+        return new byte[0];
+    }
+}
diff --git a/app/src/main/java/safeluck/drive/evaluation/bean/RegisterMessage.java b/app/src/main/java/safeluck/drive/evaluation/bean/RegisterMessage.java
new file mode 100644
index 0000000..5565ee1
--- /dev/null
+++ b/app/src/main/java/safeluck/drive/evaluation/bean/RegisterMessage.java
@@ -0,0 +1,27 @@
+package safeluck.drive.evaluation.bean;
+
+/**
+ * 娉ㄥ唽娑堟伅
+ * MyApplication2
+ * Created by lzw on 2019/12/17. 17:51:44
+ * 閭锛�632393724@qq.com
+ * All Rights Saved! Chongqing AnYun Tech co. LTD
+ */
+public class RegisterMessage extends DriveExamProtocol {
+    /**
+     * 鏋勯�犲嚱鏁�
+     *
+     * @param msg_id 娑堟伅ID
+     */
+    public RegisterMessage(short msg_id) {
+        super(msg_id);
+    }
+
+    @Override
+    protected byte[] createMessageBody() {
+        byte[] messageBody = new byte[2];
+        messageBody[0] = 0x65;
+        messageBody[1] = 0x66;
+        return messageBody;
+    }
+}
diff --git a/app/src/main/java/safeluck/drive/evaluation/bean/StartExamMessage.java b/app/src/main/java/safeluck/drive/evaluation/bean/StartExamMessage.java
new file mode 100644
index 0000000..37794ff
--- /dev/null
+++ b/app/src/main/java/safeluck/drive/evaluation/bean/StartExamMessage.java
@@ -0,0 +1,25 @@
+package safeluck.drive.evaluation.bean;
+
+/**
+ * 缁欏钩鍙板彂閫佸紑濮嬭�冭瘯娑堟伅
+ * MyApplication2
+ * Created by lzw on 2019/12/19. 18:28:47
+ * 閭锛�632393724@qq.com
+ * All Rights Saved! Chongqing AnYun Tech co. LTD
+ */
+public class StartExamMessage extends DriveExamProtocol {
+// TODO: 2019/12/19  
+    /**
+     * 鏋勯�犲嚱鏁�
+     *
+     * @param msg_id 娑堟伅ID
+     */
+    public StartExamMessage(short msg_id) {
+        super(msg_id);
+    }
+
+    @Override
+    protected byte[] createMessageBody() {
+        return new byte[0];
+    }
+}
diff --git a/app/src/main/java/safeluck/drive/evaluation/cEventCenter/CEvent.java b/app/src/main/java/safeluck/drive/evaluation/cEventCenter/CEvent.java
new file mode 100644
index 0000000..fd13504
--- /dev/null
+++ b/app/src/main/java/safeluck/drive/evaluation/cEventCenter/CEvent.java
@@ -0,0 +1,70 @@
+package safeluck.drive.evaluation.cEventCenter;
+
+/**
+ * 浜嬩欢妯″瀷锛岄渶瑕佷紶閫掔殑娑堟伅浜嬩欢瀵硅薄
+ * MyApplication2
+ * Created by lzw on 2019/12/30. 17:00:54
+ * 閭锛�632393724@qq.com
+ * All Rights Saved! Chongqing AnYun Tech co. LTD
+ */
+public class CEvent implements PooledObject {
+
+    //涓婚
+    private String topic;
+
+    private int msgCode;//娑堟伅绫诲瀷
+
+    private int resultCode;//棰勭暀鍙傛暟
+
+    private Object obj;//鍥炶皟杩斿洖鏁版嵁
+
+    public CEvent() {
+    }
+
+    public CEvent(String topic, int msgCode, int resultCode, Object obj) {
+        this.topic = topic;
+        this.msgCode = msgCode;
+        this.resultCode = resultCode;
+        this.obj = obj;
+    }
+
+    public String getTopic() {
+        return topic;
+    }
+
+    public void setTopic(String topic) {
+        this.topic = topic;
+    }
+
+    public int getMsgCode() {
+        return msgCode;
+    }
+
+    public void setMsgCode(int msgCode) {
+        this.msgCode = msgCode;
+    }
+
+    public int getResultCode() {
+        return resultCode;
+    }
+
+    public void setResultCode(int resultCode) {
+        this.resultCode = resultCode;
+    }
+
+    public Object getObj() {
+        return obj;
+    }
+
+    public void setObj(Object obj) {
+        this.obj = obj;
+    }
+
+    @Override
+    public void reset() {
+        this.obj = null;
+        this.msgCode = 0;
+        this.resultCode = 0;
+        this.topic = null;
+    }
+}
diff --git a/app/src/main/java/safeluck/drive/evaluation/cEventCenter/ObjectPool.java b/app/src/main/java/safeluck/drive/evaluation/cEventCenter/ObjectPool.java
new file mode 100644
index 0000000..cd1478b
--- /dev/null
+++ b/app/src/main/java/safeluck/drive/evaluation/cEventCenter/ObjectPool.java
@@ -0,0 +1,55 @@
+package safeluck.drive.evaluation.cEventCenter;
+
+/**
+ * 鑷畾涔夌殑瀵硅薄姹�
+ * MyApplication2
+ * Created by lzw on 2019/12/30. 17:06:49
+ * 閭锛�632393724@qq.com
+ * All Rights Saved! Chongqing AnYun Tech co. LTD
+ */
+public abstract class ObjectPool<T extends PooledObject> {
+
+    private T[] mContainer;//瀵硅薄瀹瑰櫒
+
+    private final Object LOCK = new Object();//瀵硅薄閿�
+
+    private int length;//姣忔杩斿洖瀵硅薄閮芥斁鍒版暟鎹湯绔紝length琛ㄧず鍓嶉潰鍙敤瀵硅薄鏁�
+
+    public ObjectPool(int capacity) {
+        mContainer = createObjPool(capacity);
+    }
+
+    /**
+     * 鍒涘缓瀵硅薄姹�
+     * @param capacity 鏈�澶ч檺搴﹀閲�
+     * @return
+     */
+    protected abstract T[] createObjPool(int capacity) ;
+
+    /**
+     * 鍒涘缓涓�涓柊鐨勫璞�
+     * @return
+     */
+    protected abstract T createNewObj();
+
+
+    public final T get(){
+        //鍏堜粠姹犱腑鎵惧埌绌洪棽鐨勫璞★紝濡傛灉娌℃湁锛屽垯閲嶆柊鍒涘缓涓�涓璞�
+        T obj = findFreeObject();
+        if (null == obj){
+            obj = createNewObj();
+        }else{
+            obj.reset();
+        }
+        return obj;
+    }
+
+    /**
+     * 浠庢睜涓壘鍒扮┖闂茬殑瀵硅薄
+     * @return
+     */
+    private T findFreeObject() {
+
+        return null;
+    }
+}
diff --git a/app/src/main/java/safeluck/drive/evaluation/cEventCenter/PooledObject.java b/app/src/main/java/safeluck/drive/evaluation/cEventCenter/PooledObject.java
new file mode 100644
index 0000000..848548f
--- /dev/null
+++ b/app/src/main/java/safeluck/drive/evaluation/cEventCenter/PooledObject.java
@@ -0,0 +1,15 @@
+package safeluck.drive.evaluation.cEventCenter;
+
+/**
+ * 瀵硅薄姹�
+ * MyApplication2
+ * Created by lzw on 2019/12/30. 16:59:40
+ * 閭锛�632393724@qq.com
+ * All Rights Saved! Chongqing AnYun Tech co. LTD
+ */
+public interface PooledObject {
+    /**
+     * 鎭㈠鍒伴粯璁ょ姸鎬�
+     */
+    void reset();
+}
diff --git a/app/src/main/java/safeluck/drive/evaluation/fragment/TcpFragment.java b/app/src/main/java/safeluck/drive/evaluation/fragment/TcpFragment.java
index bfe5efb..df4e056 100644
--- a/app/src/main/java/safeluck/drive/evaluation/fragment/TcpFragment.java
+++ b/app/src/main/java/safeluck/drive/evaluation/fragment/TcpFragment.java
@@ -10,6 +10,7 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.Button;
+import android.widget.TextView;
 import android.widget.Toast;
 
 import androidx.appcompat.widget.AppCompatEditText;
@@ -31,6 +32,8 @@
 import safeluck.drive.evaluation.DB.failitems.FailedProj;
 import safeluck.drive.evaluation.DB.failitems.FailedProj_select;
 import safeluck.drive.evaluation.R;
+import safeluck.drive.evaluation.im.IMSClientBootstrap;
+import safeluck.drive.evaluation.im.MessageProcessor;
 import safeluck.drive.evaluation.tcp.ConnectThread;
 
 /**
@@ -45,9 +48,9 @@
     private static final String TAG = TcpFragment.class.getSimpleName();
     private TextInputEditText ip;
     private TextInputEditText port;
+    private TextView tv_content;
     private Button btn_connect;
     private Button btn_send;
-    private      ConnectThread connectThread;
     private AppCompatEditText sendEditText;
     private CriteriaIViewModel workViewModel;
     private int item_id=0;
@@ -61,7 +64,7 @@
     public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
         View view = inflater.inflate(R.layout.layout_tcpclient, container, false);
         initView(view);
-        workViewModel =ViewModelProviders.of(this).get(CriteriaIViewModel.class);
+//        workViewModel =ViewModelProviders.of(this).get(CriteriaIViewModel.class);
 
   
         return view;
@@ -71,6 +74,7 @@
         ip = view.findViewById(R.id.input_ip);
         port = view.findViewById(R.id.input_port);
         sendEditText = view.findViewById(R.id.sendtxt);
+        tv_content = view.findViewById(R.id.content);
 
         btn_connect = view.findViewById(R.id.btn_connect);
         btn_send = view.findViewById(R.id.btn_send);
@@ -83,22 +87,37 @@
     public void onClick(View v) {
         switch (v.getId()){
             case R.id.btn_connect:
+
 //                String serverIp = ip.getText().toString().trim();
 //                String serverPort = port.getText().toStrirng().trim();
 //            connectThread = new ConnectThread(serverIp,Integer.parseInt(serverPort));
 //            connectThread.start();
-                    Random random = new Random();
-                r = random.nextInt(30)+1;
-                Log.i(TAG, "onClick: 闅忔満鏁�="+r);
-                WorkRoomDataBase.dataBaseWriteExecutor.execute(new Runnable() {
-                    @Override
-                    public void run() {
 
-                WorkRoomDataBase.getWorkRoomDataBase(getContext().getApplicationContext()).getFailProjDao().insert(new FailedProj(flag?1:2, r,flag?1001:1000));
-                flag = !flag;
-                    }
-                });
+                /**======================浠ヤ笅鐢ㄤ簬娴嬭瘯鏁版嵁搴�==================*/
+//                Random random = new Random();
+//                r = random.nextInt(30)+1;
+//                Log.i(TAG, "onClick: 闅忔満鏁�="+r);
+//                WorkRoomDataBase.dataBaseWriteExecutor.execute(new Runnable() {
+//                    @Override
+//                    public void run() {
+//
+//                WorkRoomDataBase.getWorkRoomDataBase(getContext().getApplicationContext()).getFailProjDao().insert(new FailedProj(flag?1:2, r,flag?1001:1000));
+//                flag = !flag;
+//                    }
+//                });
+                /**======================娴嬭瘯鏁版嵁搴撶粨鏉�==================*/
 
+
+
+
+
+
+
+                String userId = "100002";
+                String token = "token_" + userId;
+                String hosts = "[{\"host\":\"192.168.10.234\", \"port\":8855}]";
+
+                IMSClientBootstrap.getInstance().init(userId,token,hosts,1);
                 break;
             case R.id.btn_send:
 //                if (connectThread != null){
@@ -106,6 +125,11 @@
 ////                    sendEditText.getText().clear();
 ////                }
 
+
+
+                MessageProcessor.getInstance().sendMessage(sendEditText.getText().toString().trim());
+                sendEditText.getText().clear();
+
                 break;
         }
     }
diff --git a/app/src/main/java/safeluck/drive/evaluation/fragment/TrainFragment.java b/app/src/main/java/safeluck/drive/evaluation/fragment/TrainFragment.java
index 0ace87a..d2a793d 100644
--- a/app/src/main/java/safeluck/drive/evaluation/fragment/TrainFragment.java
+++ b/app/src/main/java/safeluck/drive/evaluation/fragment/TrainFragment.java
@@ -67,7 +67,7 @@
 
 
         FailedProjViewModel failedProjViewModel =ViewModelProviders.of(this).get(FailedProjViewModel.class);
-        failedProjViewModel.getFailedProjectsForI(1000).observe(this, new Observer<List<FailedProj_select>>() {
+        failedProjViewModel.getFailedProjectsForI(1001).observe(this, new Observer<List<FailedProj_select>>() {
             @Override
             public void onChanged(List<FailedProj_select> failedProj_selects) {
                 item_id = 0;
diff --git a/app/src/main/java/safeluck/drive/evaluation/im/IMSClientBootstrap.java b/app/src/main/java/safeluck/drive/evaluation/im/IMSClientBootstrap.java
new file mode 100644
index 0000000..056a296
--- /dev/null
+++ b/app/src/main/java/safeluck/drive/evaluation/im/IMSClientBootstrap.java
@@ -0,0 +1,109 @@
+package safeluck.drive.evaluation.im;
+
+import android.util.Log;
+
+import com.anyun.im_lib.interf.IMSClientInteface;
+import com.google.gson.Gson;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import com.google.gson.reflect.TypeToken;
+
+
+import java.lang.reflect.Type;
+import java.util.Vector;
+
+
+
+/**
+ * MyApplication2
+ * Created by lzw on 2019/12/12. 16:05:30
+ * 閭锛�632393724@qq.com
+ * All Rights Saved! Chongqing AnYun Tech co. LTD
+ */
+public class IMSClientBootstrap {
+
+    private static final String TAG = "IMSClientBootstrap";
+
+    private static final IMSClientBootstrap INSTANCE= new  IMSClientBootstrap();
+    private IMSClientInteface imsClient;
+
+    /**鏍囪IMSClientBootstrap鏄惁宸茬粡鍒濆鍖�**/
+    private boolean isActive;
+
+
+    private IMSClientBootstrap(){
+
+    }
+
+    public static IMSClientBootstrap getInstance(){
+        return  INSTANCE;
+    }
+
+    /**
+     *
+     * @param userId
+     * @param token
+     * @param hosts
+     * @param appStatus
+     */
+    public synchronized void init(String userId,String token,String hosts,int appStatus){
+        if (!isActive){
+            Vector<String> serverUrlList = convertHosts(hosts);
+            if (serverUrlList == null || serverUrlList.size() ==0){
+                Log.i(TAG, "init IMLibClientBootstrap error,ims hosts is null");
+                return;
+            }
+            isActive = true;
+            Log.i(TAG, "init IMLibClientBootstrap ,server="+hosts);
+            if (null != imsClient){
+                imsClient.close();
+            }
+            //鍒濆鍖朓MSClientInteface
+            imsClient = IMSClientFactory.getIMSClient();
+            updateAppStatus(appStatus);
+            imsClient.init(serverUrlList,new IMSEventListener(userId,token),new IMSConnectStatusListener());
+        }
+
+    }
+
+
+public boolean isActive(){
+        return isActive;
+}
+
+    public void updateAppStatus(int appStatus) {
+        if (imsClient == null){
+            return;
+        }
+        imsClient.setAppStatus(appStatus);
+    }
+
+    private Vector<String> convertHosts(String hosts) {
+        Log.i(TAG, "convertHosts: "+hosts);
+        if (hosts != null && hosts.length() > 0) {
+
+            Vector<String> serverUrlList = new Vector<>();
+            JsonArray jsonArray =JsonParser.parseString(hosts).getAsJsonArray();
+            for (int i = 0; i < jsonArray.size(); i++) {
+                JsonObject host = jsonArray.get(i).getAsJsonObject();
+                String hostName = host.get("host").getAsString();
+                int port = host.get("port").getAsInt();
+
+                Log.i(TAG, "convertHosts: hostname="+hostName+"  port="+port);
+                serverUrlList.add(hostName+" "+port);
+            }
+                return serverUrlList;
+
+
+
+        }
+        return null;
+    }
+
+    public void sendMessage(String message){
+        if (isActive){
+            imsClient.sendMsg(message);
+        }
+    }
+}
diff --git a/app/src/main/java/safeluck/drive/evaluation/im/IMSClientFactory.java b/app/src/main/java/safeluck/drive/evaluation/im/IMSClientFactory.java
new file mode 100644
index 0000000..b196d4e
--- /dev/null
+++ b/app/src/main/java/safeluck/drive/evaluation/im/IMSClientFactory.java
@@ -0,0 +1,16 @@
+package safeluck.drive.evaluation.im;
+
+import com.anyun.im_lib.interf.IMSClientInteface;
+import com.anyun.im_lib.netty.NettyTcpClient;
+
+/**
+ * MyApplication2
+ * Created by lzw on 2019/12/2. 13:13:44
+ * 閭锛�632393724@qq.com
+ * All Rights Saved! Chongqing AnYun Tech co. LTD
+ */
+public class IMSClientFactory {
+    public static IMSClientInteface getIMSClient() {
+        return NettyTcpClient.getInstance();
+    }
+}
diff --git a/app/src/main/java/safeluck/drive/evaluation/im/IMSConnectStatusListener.java b/app/src/main/java/safeluck/drive/evaluation/im/IMSConnectStatusListener.java
new file mode 100644
index 0000000..21b0d20
--- /dev/null
+++ b/app/src/main/java/safeluck/drive/evaluation/im/IMSConnectStatusListener.java
@@ -0,0 +1,31 @@
+package safeluck.drive.evaluation.im;
+
+import android.util.Log;
+
+import com.anyun.im_lib.listener.IMSConnectStatusCallback;
+
+/**
+ * MyApplication2
+ * Created by lzw on 2019/12/12. 16:30:33
+ * 閭锛�632393724@qq.com
+ * All Rights Saved! Chongqing AnYun Tech co. LTD
+ */
+public class IMSConnectStatusListener implements IMSConnectStatusCallback {
+    
+    private static final String TAG = IMSConnectStatusListener.class.getSimpleName();
+    
+    @Override
+    public void onConnecting() {
+        Log.i(TAG, "onConnecting: ");
+    }
+
+    @Override
+    public void onConnected() {
+        Log.i(TAG, "onConnected: ");
+    }
+
+    @Override
+    public void onConnectFailed() {
+        Log.i(TAG, "onConnectFailed: ");
+    }
+}
diff --git a/app/src/main/java/safeluck/drive/evaluation/im/IMSEventListener.java b/app/src/main/java/safeluck/drive/evaluation/im/IMSEventListener.java
new file mode 100644
index 0000000..18a7590
--- /dev/null
+++ b/app/src/main/java/safeluck/drive/evaluation/im/IMSEventListener.java
@@ -0,0 +1,76 @@
+package safeluck.drive.evaluation.im;
+
+import com.anyun.im_lib.listener.OnEventListener;
+
+import safeluck.drive.evaluation.bean.RegisterMessage;
+
+/**
+ * MyApplication2
+ * Created by lzw on 2019/12/12. 16:12:40
+ * 閭锛�632393724@qq.com
+ * All Rights Saved! Chongqing AnYun Tech co. LTD
+ */
+public class IMSEventListener implements OnEventListener {
+
+    private String userId;
+    private String token;
+
+    public IMSEventListener(String userId, String token) {
+        this.userId = userId;
+        this.token = token;
+    }
+
+    @Override
+    public void dispatchMsg(Object message) {
+        MessageProcessor.getInstance().receiveMsg((String)message);
+    }
+
+    @Override
+    public boolean isNetWorkAvailable() {
+        return true;
+    }
+
+    /**
+     * 杩炴帴瓒呮椂鏃堕暱
+     * @return  ms
+     */
+    @Override
+    public int getConnectTimeout() {
+        return 3000;
+    }
+
+    @Override
+    public int getForegroundHeartbeatInterval() {
+        return 0;
+    }
+
+    @Override
+    public int getBackgroundHeartbeatInterval() {
+        return 0;
+    }
+
+    @Override
+    public int getServerSentReportMsgType() {
+        return 0;
+    }
+
+    @Override
+    public int getResendCount() {
+        return 0;
+    }
+
+    @Override
+    public int getResendInterval() {
+        return 0;
+    }
+
+    @Override
+    public int getReConnectInterval() {
+        return 0;
+    }
+
+    @Override
+    public byte[] getRegisterMessage() {
+        return new RegisterMessage((short) 0x802).toBytes();
+    }
+}
diff --git a/app/src/main/java/safeluck/drive/evaluation/im/IMessageProcessor.java b/app/src/main/java/safeluck/drive/evaluation/im/IMessageProcessor.java
new file mode 100644
index 0000000..edc2c6c
--- /dev/null
+++ b/app/src/main/java/safeluck/drive/evaluation/im/IMessageProcessor.java
@@ -0,0 +1,12 @@
+package safeluck.drive.evaluation.im;
+
+/**
+ * MyApplication2
+ * Created by lzw on 2019/12/12. 16:14:57
+ * 閭锛�632393724@qq.com
+ * All Rights Saved! Chongqing AnYun Tech co. LTD
+ */
+public interface IMessageProcessor {
+    void receiveMsg(String message);
+    void sendMessage(String msg);
+}
diff --git a/app/src/main/java/safeluck/drive/evaluation/im/MessageProcessor.java b/app/src/main/java/safeluck/drive/evaluation/im/MessageProcessor.java
new file mode 100644
index 0000000..2b3e333
--- /dev/null
+++ b/app/src/main/java/safeluck/drive/evaluation/im/MessageProcessor.java
@@ -0,0 +1,48 @@
+package safeluck.drive.evaluation.im;
+
+import android.util.Log;
+
+import safeluck.drive.evaluation.util.CThreadPoolExecutor;
+
+/**
+ * MyApplication2
+ * Created by lzw on 2019/12/12. 16:14:33
+ * 閭锛�632393724@qq.com
+ * All Rights Saved! Chongqing AnYun Tech co. LTD
+ */
+public class MessageProcessor implements IMessageProcessor {
+
+    private static final String TAG = MessageProcessor.class.getSimpleName();
+
+    private MessageProcessor(){
+
+    }
+
+    private static class MessageProcessorInstance{
+        private static final IMessageProcessor INSTANCE = new MessageProcessor();
+    }
+
+    public static IMessageProcessor getInstance(){
+        return MessageProcessorInstance.INSTANCE;
+    }
+
+    @Override
+    public void receiveMsg(String message) {
+        Log.i(TAG, "receiveMsg: "+message);
+    }
+
+    @Override
+    public void sendMessage(final String msg) {
+        CThreadPoolExecutor.runInBackground(new Runnable() {
+            @Override
+            public void run() {
+                if (IMSClientBootstrap.getInstance().isActive()){
+
+                    IMSClientBootstrap.getInstance().sendMessage(msg);
+                }else{
+                    Log.e(TAG, "run: 鍙戦�佹秷鎭け璐ワ紝鏈垵濮嬪寲杩炴帴NettyTcp");
+                }
+            }
+        });
+    }
+}
diff --git a/app/src/main/java/safeluck/drive/evaluation/im/handler/AbstractMessageHandler.java b/app/src/main/java/safeluck/drive/evaluation/im/handler/AbstractMessageHandler.java
new file mode 100644
index 0000000..4755ea6
--- /dev/null
+++ b/app/src/main/java/safeluck/drive/evaluation/im/handler/AbstractMessageHandler.java
@@ -0,0 +1,15 @@
+package safeluck.drive.evaluation.im.handler;
+
+/**
+ * MyApplication2
+ * Created by lzw on 2019/12/12. 16:09:02
+ * 閭锛�632393724@qq.com
+ * All Rights Saved! Chongqing AnYun Tech co. LTD
+ */
+public abstract class AbstractMessageHandler implements IMessageHandler {
+    @Override
+    public void execute(String msg) {
+        action(msg);
+    }
+    protected abstract void action(String msg);
+}
diff --git a/app/src/main/java/safeluck/drive/evaluation/im/handler/IMessageHandler.java b/app/src/main/java/safeluck/drive/evaluation/im/handler/IMessageHandler.java
new file mode 100644
index 0000000..020efff
--- /dev/null
+++ b/app/src/main/java/safeluck/drive/evaluation/im/handler/IMessageHandler.java
@@ -0,0 +1,11 @@
+package safeluck.drive.evaluation.im.handler;
+
+/**
+ * MyApplication2
+ * Created by lzw on 2019/12/12. 16:04:29
+ * 閭锛�632393724@qq.com
+ * All Rights Saved! Chongqing AnYun Tech co. LTD
+ */
+public interface IMessageHandler {
+    void execute(String msg);
+}
diff --git a/app/src/main/java/safeluck/drive/evaluation/util/CThreadPoolExecutor.java b/app/src/main/java/safeluck/drive/evaluation/util/CThreadPoolExecutor.java
new file mode 100644
index 0000000..5600b3c
--- /dev/null
+++ b/app/src/main/java/safeluck/drive/evaluation/util/CThreadPoolExecutor.java
@@ -0,0 +1,332 @@
+package safeluck.drive.evaluation.util;
+
+
+import android.os.Handler;
+import android.os.Looper;
+import android.util.Log;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * MyApplication2
+ * Created by lzw on 2019/12/12. 16:22:49
+ * 閭锛�632393724@qq.com
+ * All Rights Saved! Chongqing AnYun Tech co. LTD
+ *
+ *  *
+ *  * <p>@ClassName:       CThreadPoolExecutor.java</p>
+ *  * <b>
+ *  * <p>@Description:     鑷畾涔夊浐瀹氬ぇ灏忕殑绾跨▼姹�
+ *  * 姣忔鎻愪氦涓�涓换鍔″氨鍒涘缓涓�涓嚎绋嬶紝鐩村埌绾跨▼杈惧埌绾跨▼姹犵殑鏈�澶уぇ灏忋��
+ *  * 绾跨▼姹犵殑澶у皬涓�鏃﹁揪鍒版渶澶у�煎氨浼氫繚鎸佷笉鍙橈紝濡傛灉鏌愪釜绾跨▼鍥犱负鎵ц寮傚父鑰岀粨鏉燂紝閭d箞绾跨▼姹犱細琛ュ厖涓�涓柊绾跨▼銆�
+ *  * <p>
+ *  * 鍚堢悊鍒╃敤绾跨▼姹犺兘澶熷甫鏉ヤ笁涓ソ澶勶細
+ *  * 绗竴锛氶檷浣庤祫婧愭秷鑰椼�傞�氳繃閲嶅鍒╃敤宸插垱寤虹殑绾跨▼闄嶄綆绾跨▼鍒涘缓鍜岄攢姣侀�犳垚鐨勬秷鑰椼��
+ *  * 绗簩锛氭彁楂樺搷搴旈�熷害銆傚綋浠诲姟鍒拌揪鏃讹紝浠诲姟鍙互涓嶉渶瑕佺瓑鍒扮嚎绋嬪垱寤哄氨鑳界珛鍗虫墽琛屻��
+ *  * 绗笁锛氭彁楂樼嚎绋嬬殑鍙鐞嗘�с�傜嚎绋嬫槸绋�缂鸿祫婧愶紝濡傛灉鏃犻檺鍒剁殑鍒涘缓锛屼笉浠呬細娑堣�楃郴缁熻祫婧愶紝杩樹細闄嶄綆绯荤粺鐨勭ǔ瀹氭�э紝浣跨敤绾跨▼姹犲彲浠ヨ繘琛岀粺涓�鐨勫垎閰嶏紝璋冧紭鍜岀洃鎺с��
+ *  * 鎴戜滑鍙互閫氳繃ThreadPoolExecutor鏉ュ垱寤轰竴涓嚎绋嬫睜锛�
+ *  * new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, milliseconds,runnableTaskQueue, handler);
+ *  * <p>
+ *  * corePoolSize锛堢嚎绋嬫睜鐨勫熀鏈ぇ灏忥級锛�
+ *  * 褰撴彁浜や竴涓换鍔″埌绾跨▼姹犳椂锛岀嚎绋嬫睜浼氬垱寤轰竴涓嚎绋嬫潵鎵ц浠诲姟锛�
+ *  * 鍗充娇鍏朵粬绌洪棽鐨勫熀鏈嚎绋嬭兘澶熸墽琛屾柊浠诲姟涔熶細鍒涘缓绾跨▼锛岀瓑鍒伴渶瑕佹墽琛岀殑浠诲姟鏁板ぇ浜庣嚎绋嬫睜鍩烘湰澶у皬鏃跺氨涓嶅啀鍒涘缓銆�
+ *  * 濡傛灉璋冪敤浜嗙嚎绋嬫睜鐨刾restartAllCoreThreads鏂规硶锛岀嚎绋嬫睜浼氭彁鍓嶅垱寤哄苟鍚姩鎵�鏈夊熀鏈嚎绋嬨��
+ *  * <p>
+ *  * runnableTaskQueue锛堜换鍔¢槦鍒楋級锛氱敤浜庝繚瀛樼瓑寰呮墽琛岀殑浠诲姟鐨勯樆濉為槦鍒椼�� 鍙互閫夋嫨浠ヤ笅鍑犱釜闃诲闃熷垪銆�
+ *  * ArrayBlockingQueue锛氭槸涓�涓熀浜庢暟缁勭粨鏋勭殑鏈夌晫闃诲闃熷垪锛屾闃熷垪鎸� FIFO锛堝厛杩涘厛鍑猴級鍘熷垯瀵瑰厓绱犺繘琛屾帓搴忋��
+ *  * <p>
+ *  * LinkedBlockingQueue锛氫竴涓熀浜庨摼琛ㄧ粨鏋勭殑闃诲闃熷垪锛屾闃熷垪鎸塅IFO 锛堝厛杩涘厛鍑猴級 鎺掑簭鍏冪礌锛屽悶鍚愰噺閫氬父瑕侀珮浜嶢rrayBlockingQueue銆�
+ *  * 闈欐�佸伐鍘傛柟娉旹xecutors.newFixedThreadPool()浣跨敤浜嗚繖涓槦鍒椼��
+ *  * <p>
+ *  * SynchronousQueue锛氫竴涓笉瀛樺偍鍏冪礌鐨勯樆濉為槦鍒椼�傛瘡涓彃鍏ユ搷浣滃繀椤荤瓑鍒板彟涓�涓嚎绋嬭皟鐢ㄧЩ闄ゆ搷浣滐紝鍚﹀垯鎻掑叆鎿嶄綔涓�鐩村浜庨樆濉炵姸鎬侊紝
+ *  * 鍚炲悙閲忛�氬父瑕侀珮浜嶭inkedBlockingQueue锛岄潤鎬佸伐鍘傛柟娉旹xecutors.newCachedThreadPool浣跨敤浜嗚繖涓槦鍒椼��
+ *  * <p>
+ *  * PriorityBlockingQueue锛氫竴涓叿鏈変紭鍏堢骇鐨勬棤闄愰樆濉為槦鍒椼��
+ *  * <p>
+ *  * maximumPoolSize锛堢嚎绋嬫睜鏈�澶уぇ灏忥級锛�
+ *  * 绾跨▼姹犲厑璁稿垱寤虹殑鏈�澶х嚎绋嬫暟銆傚鏋滈槦鍒楁弧浜嗭紝骞朵笖宸插垱寤虹殑绾跨▼鏁板皬浜庢渶澶х嚎绋嬫暟锛屽垯绾跨▼姹犱細鍐嶅垱寤烘柊鐨勭嚎绋嬫墽琛屼换鍔°�傚�煎緱娉ㄦ剰鐨勬槸濡傛灉浣跨敤浜嗘棤鐣岀殑浠诲姟闃熷垪杩欎釜鍙傛暟灏辨病浠�涔堟晥鏋溿��
+ *  * <p>
+ *  * ThreadFactory锛�
+ *  * 鐢ㄤ簬璁剧疆鍒涘缓绾跨▼鐨勫伐鍘傦紝鍙互閫氳繃绾跨▼宸ュ巶缁欐瘡涓垱寤哄嚭鏉ョ殑绾跨▼璁剧疆鏇存湁鎰忎箟鐨勫悕瀛椼��
+ *  * <p>
+ *  * RejectedExecutionHandler锛堥ケ鍜岀瓥鐣ワ級锛氬綋闃熷垪鍜岀嚎绋嬫睜閮芥弧浜嗭紝璇存槑绾跨▼姹犲浜庨ケ鍜岀姸鎬侊紝閭d箞蹇呴』閲囧彇涓�绉嶇瓥鐣ュ鐞嗘彁浜ょ殑鏂颁换鍔°��
+ *  * 杩欎釜绛栫暐榛樿鎯呭喌涓嬫槸AbortPolicy锛岃〃绀烘棤娉曞鐞嗘柊浠诲姟鏃舵姏鍑哄紓甯搞�備互涓嬫槸JDK1.5鎻愪緵鐨勫洓绉嶇瓥鐣ャ��
+ *  * AbortPolicy锛氱洿鎺ユ姏鍑哄紓甯搞��
+ *  * CallerRunsPolicy锛氬彧鐢ㄨ皟鐢ㄨ�呮墍鍦ㄧ嚎绋嬫潵杩愯浠诲姟銆�
+ *  * DiscardOldestPolicy锛氫涪寮冮槦鍒楅噷鏈�杩戠殑涓�涓换鍔★紝骞舵墽琛屽綋鍓嶄换鍔°��
+ *  * DiscardPolicy锛氫笉澶勭悊锛屼涪寮冩帀銆�
+ *  * 褰撶劧涔熷彲浠ユ牴鎹簲鐢ㄥ満鏅渶瑕佹潵瀹炵幇RejectedExecutionHandler鎺ュ彛鑷畾涔夌瓥鐣ャ�傚璁板綍鏃ュ織鎴栨寔涔呭寲涓嶈兘澶勭悊鐨勪换鍔°��
+ *  * <p>
+ *  * keepAliveTime锛堢嚎绋嬫椿鍔ㄤ繚鎸佹椂闂达級锛氱嚎绋嬫睜鐨勫伐浣滅嚎绋嬬┖闂插悗锛屼繚鎸佸瓨娲荤殑鏃堕棿銆�
+ *  * 鎵�浠ュ鏋滀换鍔″緢澶氾紝骞朵笖姣忎釜浠诲姟鎵ц鐨勬椂闂存瘮杈冪煭锛屽彲浠ヨ皟澶ц繖涓椂闂达紝鎻愰珮绾跨▼鐨勫埄鐢ㄧ巼銆�
+ *  * <p>
+ *  * TimeUnit锛堢嚎绋嬫椿鍔ㄤ繚鎸佹椂闂寸殑鍗曚綅锛夛細鍙�夌殑鍗曚綅鏈夊ぉ锛圖AYS锛夛紝灏忔椂锛圚OURS锛夛紝鍒嗛挓锛圡INUTES锛夛紝
+ *  * 姣(MILLISECONDS)锛屽井绉�(MICROSECONDS, 鍗冨垎涔嬩竴姣)鍜屾寰(NANOSECONDS, 鍗冨垎涔嬩竴寰)銆�</p>
+ *  * </b>
+ *  * <p>@author:          FreddyChen</p>
+ *  * <p>@date:            2019/2/3 15:35</p>
+ *  * <p>@email:           chenshichao@outlook.com</p>
+ *  *
+ *  * @see http://www.infoq.com/cn/articles/java-threadPool
+ *
+ */
+public class CThreadPoolExecutor {
+    private static final String TAG = CThreadPoolExecutor.class.getSimpleName();
+    private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();// CPU涓暟
+    //    private static final int CORE_POOL_SIZE = CPU_COUNT + 1;// 绾跨▼姹犱腑鏍稿績绾跨▼鐨勬暟閲�
+//    private static final int MAXIMUM_POOL_SIZE = 2 * CPU_COUNT + 1;// 绾跨▼姹犱腑鏈�澶х嚎绋嬫暟閲�
+    private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));// 绾跨▼姹犱腑鏍稿績绾跨▼鐨勬暟閲�
+    private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;// 绾跨▼姹犱腑鏈�澶х嚎绋嬫暟閲�
+    private static final long KEEP_ALIVE_TIME = 30L;// 闈炴牳蹇冪嚎绋嬬殑瓒呮椂鏃堕暱锛屽綋绯荤粺涓潪鏍稿績绾跨▼闂茬疆鏃堕棿瓒呰繃keepAliveTime涔嬪悗锛屽垯浼氳鍥炴敹銆傚鏋淭hreadPoolExecutor鐨刟llowCoreThreadTimeOut灞炴�ц缃负true锛屽垯璇ュ弬鏁颁篃琛ㄧず鏍稿績绾跨▼鐨勮秴鏃舵椂闀�
+    private static final int WAIT_COUNT = 128; // 鏈�澶氭帓闃熶釜鏁帮紝杩欓噷鎺у埗绾跨▼鍒涘缓鐨勯鐜�
+
+    private static ThreadPoolExecutor pool = createThreadPoolExecutor();
+
+    private static ThreadPoolExecutor createThreadPoolExecutor() {
+        if (pool == null) {
+            pool = new ThreadPoolExecutor(
+                    CORE_POOL_SIZE,
+                    MAXIMUM_POOL_SIZE,
+                    KEEP_ALIVE_TIME,
+                    TimeUnit.SECONDS,
+                    new LinkedBlockingQueue<Runnable>(WAIT_COUNT),
+                    new CThreadFactory("CThreadPool", Thread.NORM_PRIORITY - 2),
+                    new CHandlerException());
+        }
+
+        return pool;
+    }
+
+    public static class CThreadFactory implements ThreadFactory {
+        private AtomicInteger counter = new AtomicInteger(1);
+        private String prefix = "";
+        private int priority = Thread.NORM_PRIORITY;
+
+        public CThreadFactory(String prefix, int priority) {
+            this.prefix = prefix;
+            this.priority = priority;
+        }
+
+        public CThreadFactory(String prefix) {
+            this.prefix = prefix;
+        }
+
+        public Thread newThread(Runnable r) {
+            Thread executor = new Thread(r, prefix + " #" + counter.getAndIncrement());
+            executor.setDaemon(true);
+            executor.setPriority(priority);
+            return executor;
+        }
+    }
+
+    /**
+     * 鎶涘純褰撳墠鐨勪换鍔�
+     */
+    private static class CHandlerException extends ThreadPoolExecutor.AbortPolicy {
+
+        @Override
+        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
+            Log.d(TAG, "rejectedExecution:" + r);
+            Log.e(TAG, logAllThreadStackTrace().toString());
+            //            Tips.showForce("浠诲姟琚嫆缁�", 5000);
+            if (!pool.isShutdown()) {
+                pool.shutdown();
+                pool = null;
+            }
+
+            pool = createThreadPoolExecutor();
+        }
+    }
+
+    private static ExecutorService jobsForUI = Executors.newFixedThreadPool(
+            CORE_POOL_SIZE, new CThreadFactory("CJobsForUI", Thread.NORM_PRIORITY - 1));
+
+    /**
+     * 鍚姩涓�涓秷鑰楃嚎绋嬶紝甯搁┗鍚庡彴
+     *
+     * @param r
+     */
+    public static void startConsumer(final Runnable r, final String name) {
+        runInBackground(new Runnable() {
+            public void run() {
+                new CThreadFactory(name, Thread.NORM_PRIORITY - 3).newThread(r).start();
+            }
+        });
+    }
+
+    /**
+     * 鎻愪氦鍒板叾浠栫嚎绋嬪幓璺戯紝闇�瑕佸彇鏁版嵁鐨勬椂鍊欎細绛夊緟浠诲姟瀹屾垚鍐嶇户缁�
+     *
+     * @param task
+     * @return
+     */
+    public static <T> Future<T> submitTask(Callable<T> task) {
+        return jobsForUI.submit(task);
+    }
+
+    /**
+     * 寮哄埗娓呯悊浠诲姟
+     *
+     * @param task
+     * @return
+     */
+    public static <T> void cancelTask(Future<T> task) {
+        if (task != null) {
+            task.cancel(true);
+        }
+    }
+
+    /**
+     * 浠� Future 涓幏鍙栧�硷紝濡傛灉鍙戠敓寮傚父锛屾墦鏃ュ織
+     *
+     * @param future
+     * @param tag
+     * @param name
+     * @return
+     */
+    public static <T> T getFromTask(Future<T> future, String tag, String name) {
+        try {
+            return future.get();
+        } catch (Exception e) {
+            Log.e(tag, (name != null ? name + ": " : "") + e.toString());
+        }
+        return null;
+    }
+
+    public static void runInBackground(Runnable runnable) {
+        if (pool == null) {
+            createThreadPoolExecutor();
+        }
+
+        pool.execute(runnable);
+        //        Future future = pool.submit(runnable);
+        //        try {
+        //            future.get();
+        //        } catch (InterruptedException e) {
+        //            e.printStackTrace();
+        //        } catch (ExecutionException e) {
+        //            e.printStackTrace();
+        //        }
+    }
+
+    private static Thread mainThread;
+    private static Handler mainHandler;
+
+    static {
+        Looper mainLooper = Looper.getMainLooper();
+        mainThread = mainLooper.getThread();
+        mainHandler = new Handler(mainLooper);
+    }
+
+    public static boolean isOnMainThread() {
+        return mainThread == Thread.currentThread();
+    }
+
+    public static void runOnMainThread(Runnable r) {
+        if (isOnMainThread()) {
+            r.run();
+        } else {
+            mainHandler.post(r);
+        }
+    }
+
+    public static void runOnMainThread(Runnable r, long delayMillis) {
+        if (delayMillis <= 0) {
+            runOnMainThread(r);
+        } else {
+            mainHandler.postDelayed(r, delayMillis);
+        }
+    }
+
+    // 鐢ㄤ簬璁板綍鍚庡彴绛夊緟鐨凴unnable锛岀涓�涓弬鏁板闈㈢殑Runnable锛岀浜屼釜鍙傛暟鏄瓑寰呬腑鐨凴unnable
+    private static HashMap<Runnable, Runnable> mapToMainHandler = new HashMap<Runnable, Runnable>();
+
+    public static void runInBackground(final Runnable runnable, long delayMillis) {
+        if (delayMillis <= 0) {
+            runInBackground(runnable);
+        } else {
+            Runnable mainRunnable = new Runnable() {
+
+                @Override
+                public void run() {
+                    mapToMainHandler.remove(runnable);
+                    pool.execute(runnable);
+                }
+            };
+
+            mapToMainHandler.put(runnable, mainRunnable);
+            mainHandler.postDelayed(mainRunnable, delayMillis);
+        }
+    }
+
+    /**
+     * 瀵箁unOnMainThread鐨勶紝绉婚櫎Runnable
+     *
+     * @param r
+     */
+    public static void removeCallbackOnMainThread(Runnable r) {
+        mainHandler.removeCallbacks(r);
+    }
+
+    public static void removeCallbackInBackground(Runnable runnable) {
+        Runnable mainRunnable = mapToMainHandler.get(runnable);
+        if (mainRunnable != null) {
+            mainHandler.removeCallbacks(mainRunnable);
+        }
+    }
+
+    public static void logStatus() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("getActiveCount");
+        sb.append(pool.getActiveCount());
+        sb.append("\ngetTaskCount");
+        sb.append(pool.getTaskCount());
+        sb.append("\ngetCompletedTaskCount");
+        sb.append(pool.getCompletedTaskCount());
+        Log.d(TAG, sb.toString());
+    }
+
+    public static StringBuilder logAllThreadStackTrace() {
+        StringBuilder builder = new StringBuilder();
+        Map<Thread, StackTraceElement[]> liveThreads = Thread.getAllStackTraces();
+        for (Iterator<Thread> i = liveThreads.keySet().iterator(); i.hasNext(); ) {
+            Thread key = i.next();
+            builder.append("Thread ").append(key.getName())
+                    .append("\n");
+            StackTraceElement[] trace = liveThreads.get(key);
+            for (int j = 0; j < trace.length; j++) {
+                builder.append("\tat ").append(trace[j]).append("\n");
+            }
+        }
+        return builder;
+    }
+
+    public static void main(String[] args) {
+        for (int i = 0; i < 10000; i++) {
+            final int index = i;
+            System.out.println("index=" + index);
+            CThreadPoolExecutor.runInBackground(new Runnable() {
+                @Override
+                public void run() {
+                    System.out.println("姝e湪杩愯绗琜" + (index + 1) + "]涓嚎绋�.");
+                }
+            });
+            try {
+                Thread.sleep(10);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+}

--
Gitblit v1.8.0