【移动开发】Android应用程序中实用的代码框架(二)

简介:

在上次博客中,我总结了一套比较实用的代码框架,不知道有没有帮助到大家?j_0067.gif。。。(实用的代码框架http://smallwoniu.blog.51cto.com/blog/3911954/1307060)核心思想是:一个线程(在Activity中开启服务启动线程的方式)来监听处理任务队列中tasks,来对其依次处理。

细心地大家可能会发现要是任务在10个以下,框架还可以承担,要是任务过多时(主要是并发执行时),

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
      * 线程不断检测tasks中的任务
      */
     @Override
     public  void  run() {
         while (isRun) {
             Task task =  null ;
             if (!tasks.isEmpty()) {
                 task = tasks.poll();
                 if ( null  != task) {
                     doTask(task);  //处理任务
                 }
             }
             try  {
                 Thread.sleep( 1000 );
             catch  (InterruptedException e) {
                 e.printStackTrace();
             }
         }
     }



鉴于实际开发中并发执行任务的情况较多!我整理了又一款非常实用的代码框架,也可以说是上次代码框架的加强版!

这次我采用了线程池的方式处理多任务,提高程序的运行效率。

111541752.jpg

首先是简单的一些类

IActivity类

1
2
3
4
5
6
7
8
9
10
11
12
package  com.zhf.android_frameworkdemo03.threadpool;
public  interface  IActivity {
     /**
      * 初始化操作
      */
     public  abstract  void  init();
     /**
      * 刷新操作
      * @param params 可变参数
      */
     public  abstract  void  refresh( Object ... params);
}

TaskID类:

1
2
3
4
5
6
7
package  com.zhf.android_frameworkdemo03.model;
public  class  TaskID {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
     public  static  final  int  MANAGER_LOGIN =  0 ; // 管理员登录
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
     //以此类推,根据自己项目的需求添加任务ID
}

TaskOperate类:

1
2
3
4
5
6
7
8
9
10
11
12
13
package  com.zhf.android_frameworkdemo03.threadpool;
/**
  * 任务操作接口
  * @author ZHF
  *
  */
public  interface  TaskOperate {
     /**
      * 操作Task
      * @param Task Task实体
      */
     public  abstract  void  operate(Task Task);
}


接下来是重要的类

ThreadPoolManager类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
package  com.zhf.android_frameworkdemo03.threadpool;
import  java.util.Collections;
import  java.util.LinkedList;
import  java.util.List;
import  android.util.Log;
/**
  * 线程池管理器
  * @author ZHF
  *
  */
public  class  ThreadPoolManager {
     public  static  String TAG =  "ThreadPoolManager" ;
     public  static  ThreadPoolManager instance =  null ;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
     //Returns a wrapper on the specified List which synchronizes all access to the List.
     public  static  List<Task> taskQueue = Collections.synchronizedList( new  LinkedList());  //任务队列(LinkedList:便于插入和删除)
     private  WorkThread[] workQueue;   //运行的线程数组
     private  static  int  threadNumber =  5 ;   //线程池数量5
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
     /**构造方法(单例)**/
     private  ThreadPoolManager(TaskOperate taskOperate) {
         this (threadNumber, taskOperate);
     }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
     /**构造方法(单例):实例化线程数组**/
     private  ThreadPoolManager( int  threadNumber, TaskOperate taskOperate) {
         this .threadNumber = threadNumber;
         this .workQueue =  new  WorkThread[threadNumber];   //装线程数组
         for  ( int  i =  0 ; i < threadNumber; i++) {
             this .workQueue[i] =  new  WorkThread(i, taskOperate);  //将线程对应装入数组
             System.out.println( "当前运行的是" + i + "个线程" );
         }
     }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
     /**获取该类的实例对象(懒汉式)**/
     public  static  synchronized  ThreadPoolManager getInstance(TaskOperate taskOperate) {
         if (instance ==  null ) {
             instance =  new  ThreadPoolManager(taskOperate);
             return  instance;  //获取实例
         }
         return  null ;
     }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
     /**添加单个任务**/
     public  void  addTask(Task task) {
         synchronized (taskQueue) {  //锁住线程队列对象
             if (task !=  null ) {
                 taskQueue.add(task);
                 taskQueue.notifyAll();
                 System.out.println( "任务: "  + task.getTaskInfo() +  "--添加成功--" );
             }
         }
     }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
     /**添加多个任务**/
     public  void  addTasks(Task[] tasks) {
         synchronized  (taskQueue) {  //锁住线程队列对象
             for  (Task t : tasks) {  //遍历
                 if (tasks !=  null ) {
                     taskQueue.add(t);
                     taskQueue.notifyAll();
                     System.out.println( "任务: "  + t.getTaskInfo() +  "--添加成功--" );
                 }
             }
         }
     }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
     /**销毁线程**/
     public  void  destroy() {
         Log.i(TAG,  "线程池管理器destroy方法开始。。。" );
         for  ( int  i =  0 ; i < threadNumber; i++) {
             this .workQueue[i].stopThread();  //停止线程
             this .workQueue[i] =  null ;   //GC回收
         }
         synchronized (taskQueue) {  //锁住线程队列对象
             //清空队列集合
             taskQueue.clear();
         }
         Log.i(TAG,  "线程池管理器destroy方法结束。。。" );
         System.gc();  //内存回收
     }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
}

说明:

1.这里我并没有使用ThreadPoolExecutor来真正的实现线程池操作,而是用数组装载线程的方式模拟线程池操作,在实例化该类的时候(程序启动时)我们开启了5个WorkThread在后台等待执行任务。

2.该类还有两个重要的方法:

addTask()---->添加具体任务到任务队列

destroy() ---->销毁线程


WorkThread类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package  com.zhf.android_frameworkdemo03.threadpool;
import  android.util.Log;
/**
  * 工作线程
  * @author ZHF
  *
  */
public  class  WorkThread  extends  Thread {
     private  int  taskId;   //任务Id
     private  boolean  isRunning =  true ;   //线程启动标记
     private  TaskOperate taskOperate;   //任务操作接口
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         
     /**构造方法:启动线程**/
     public  WorkThread( int  taskId, TaskOperate taskOperate) {
         this .taskId = taskId;
         this .taskOperate = taskOperate;
         //启动
         this .start();
     }
     @Override
     public  void  run() {
         while (isRunning) {
             Task task =  null ;
             synchronized  (ThreadPoolManager.taskQueue) {  //线程队列
                 //线程虽然开启,但是没有任务队列中没有添加具体任务进来
                 while (isRunning && ThreadPoolManager.taskQueue.isEmpty()) {
                     try  {
                         ThreadPoolManager.taskQueue.wait(20L);
                     catch  (InterruptedException e) {
                         System.out.println( "线程"  this .taskId +  "在运行时,报InterruptedException" );
                         Log.e(ThreadPoolManager.TAG,  "线程"  this .taskId +  "在运行时,报InterruptedException" );
                         e.printStackTrace();
                     }
                 }
                 if ( this .isRunning) {
                     //移除任务
                     task = ThreadPoolManager.taskQueue.remove( 0 );
                 }
             }
             //有任务进来
             if (task !=  null ) {
                 System.out.println(task.getTaskInfo() +  "任务在线程" this .taskId +  "中开始。。。" );
                  //处理任务(调用接口中方法处理,具体实现在子类当中。多态)
                 this .taskOperate.operate(task);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     
                 System.out.println(task.getTaskInfo() +  "任务在线程"  this .taskId +  "结束中。。。" );
             }
         }
     }
     /**停止线程**/
     public  void  stopThread() {
         this .isRunning =  false ;
     }
}

说明:

该类是一个线程类,主要用于处理任务队列中任务事件,5个线程共同处理任务集合中的task,避免了先前一个线程处理task时,后一个task等待的情况,提高了系统的执行效率!


ClientTask类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package  com.zhf.android_frameworkdemo03.services;
import  android.os.Handler;
import  android.os.Message;
import  com.zhf.android_frameworkdemo03.MyApplication;
import  com.zhf.android_frameworkdemo03.handle.LoginHandler;
import  com.zhf.android_frameworkdemo03.model.TaskID;
import  com.zhf.android_frameworkdemo03.threadpool.IActivity;
import  com.zhf.android_frameworkdemo03.threadpool.Task;
import  com.zhf.android_frameworkdemo03.threadpool.TaskOperate;
/**
  * 统一处理任务类
  * @author ZHF
  *
  */
public  class  ClientTask  implements  TaskOperate{
     /**统一任务处理**/
     @Override
     public  void  operate(Task task) {
         Message message = mHandler.obtainMessage();
         message.what = task.getId();
                                                                                                                                                                                                                                                                                                                                                                                                          
         //1.根据TaskID来判断,调用对应的XXhandler来处理任务
         //2.处理完成得到返回的message.obj数据,将其统一sendMessage(message)出去
         //3.在消息处理机制mHandler中对应接收数据,刷新对应的UI界面
                                                                                                                                                                                                                                                                                                                                                                                                          
         switch  (task.getId()) {
         case  TaskID.MANAGER_LOGIN:  //管理员登陆
             //处理登录事件,获取message.obj数据
             LoginHandler.getLogin(task, message);
             break ;
                                                                                                                                                                                                                                                                                                                                                                                                              
             //此处添加后续任务
         }
         mHandler.sendMessage(message); //发送消息
     }
     /**消息处理**/
     public  Handler mHandler =  new  Handler() {
         @Override
         public  void  handleMessage(Message msg) {
             super .handleMessage(msg);
             IActivity ia =  null ;
             //根据传来的任务消息ID,来对应的传递参数刷新界面
             switch  (msg.what) {
             case  TaskID.MANAGER_LOGIN:   //管理员登陆
                 ia = MyApplication.getActivityByName( "MainActivity" );
                 ia.refresh(msg.obj);
                 break ;
                                                                                                                                                                                                                                                                                                                                                                                                                  
             //此处添加后续任务
             }
         }
     };
}

说明:

1.该类实现了先前定义的TaskOperate接口,重写了operate()处理任务,对应TaskID我们新建了一个类LoginHandler来处理,最后接收处理结果message.obj,并统一发送到mHandler接收,刷新对应的UI界面。

2.注意:该类我们实现的是客户端的一系列请求任务,当然我们还可以再定义一个类,实现TaskOperate接口,用于统一操作服务器端Task,也是可以的,扩展么!)


LoginHandler类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package  com.zhf.android_frameworkdemo03.handle;
import  com.zhf.android_frameworkdemo03.threadpool.Task;
import  android.os.Message;
/**
  * 登录事件处理
  * @author ZHF
  *
  */
public  class  LoginHandler {
                                                                                                                                                                                                     
     /**处理登录事物,将结果用消息发送出去**/
     public  static  void  getLogin(Task task, Message message) {
         //处理完成。。。。
         message.obj =  "登陆成功!" ;
     }
}


程序入口

MainActivity类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package  com.zhf.android_frameworkdemo03;
import  com.zhf.android_frameworkdemo03.model.TaskID;
import  com.zhf.android_frameworkdemo03.threadpool.IActivity;
import  com.zhf.android_frameworkdemo03.threadpool.Task;
import  android.os.Bundle;
import  android.view.View;
import  android.view.View.OnClickListener;
import  android.widget.Button;
import  android.widget.TextView;
import  android.app.Activity;
public  class  MainActivity  extends  Activity  implements  IActivity{
                                                                                                                                                              
     public  Button mBtnLogin;  //登陆按钮:测试代码框架是否运行正常
     public  TextView mTvLogin;
     @Override
     protected  void  onCreate(Bundle savedInstanceState) {
         super .onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
                                                                                                                                                                  
         //1.将要执行任务的Activity,加入到集合中
         MyApplication.allActivity.add( this );
                                                                                                                                                                  
         this .mBtnLogin = (Button) findViewById(R.id.button1);
         this .mTvLogin = (TextView) findViewById(R.id.textView1);
         mBtnLogin.setOnClickListener( new  OnClickListener() {
             @Override
             public  void  onClick(View v) {
                 //2.产生任务:对应填入参数
                 Task task =  new  Task(TaskID.MANAGER_LOGIN,  "框架测试成功!!" "---登陆任务----" );
                 //3.将当前任务加入到写好的线程池中()
                 MyApplication.poolManager.addTask(task);
             }
         });
     }
     @Override
     public  void  init() {
         // TODO Auto-generated method stub
                                                                                                                                                                  
     }
     @Override
     public  void  refresh(Object... params) {
         //接收线程处理过后返回的数据
         mTvLogin.setText(params[ 0 ].toString());
     }
}


MyApplication类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package  com.zhf.android_frameworkdemo03;
import  java.util.ArrayList;
import  com.zhf.android_frameworkdemo03.services.ClientTask;
import  com.zhf.android_frameworkdemo03.threadpool.IActivity;
import  com.zhf.android_frameworkdemo03.threadpool.ThreadPoolManager;
import  android.app.Application;
/**
  *加载配置文件,监测网络情况,初始化任务线程池
  * @author ZHF
  *
  */
public  class  MyApplication  extends  Application{
                                                                                                                                                                        
     // 所有实现接口IActivity的Activity,即放置所有要执行任务的Activity
     public  static  ArrayList<IActivity> allActivity =  new  ArrayList<IActivity>();
     public  static  ThreadPoolManager poolManager;
                                                                                                                                                                        
     /**程序启动**/
     @Override
     public  void  onCreate() {
         super .onCreate();
         //程序启动时,开启线程池(5个线程,等待task)
         poolManager = ThreadPoolManager.getInstance( new  ClientTask());
                                                                                                                                                                            
     }
                                                                                                                                                                        
     /**根据名字获取Activity**/
     public  static  IActivity getActivityByName( String  name) {
         IActivity ia =  null ;
         for  (IActivity ac : allActivity) {
             if  (ac.getClass().getName().endsWith(name)) {
                 ia = ac;
             }
         }
         return  ia;
     }
}



到此,强大的代码框架已搭建起来,我们点击一下按钮,测试一下代码吧!

151936977.png ---------》151938141.png


为了让大家看的更清楚,我打印出了后台数据!

152200402.jpg

为了显示出框架的威力!我们可以试试狂点按钮,通过后台数据,我们知道了每次处理该任务是不同的线程!

152339329.jpg


框架代码源码下载地址:http://down.51cto.com/data/1011299





     本文转自zhf651555765 51CTO博客,原文链接:http://blog.51cto.com/smallwoniu/1324842,如需转载请自行联系原作者




相关文章
|
3月前
|
Android开发 开发者
Android UI设计: 请解释Activity的Theme是什么,如何更改应用程序的主题?
Android UI设计: 请解释Activity的Theme是什么,如何更改应用程序的主题?
41 1
|
3月前
|
安全 Java 数据安全/隐私保护
Android和iOS应用程序加固方法详解:混淆、加壳、数据加密、动态加载和数字签名实现
Android和iOS应用程序加固方法详解:混淆、加壳、数据加密、动态加载和数字签名实现
66 0
|
11月前
|
Android开发
使用WakeLock使Android应用程序保持后台唤醒
使用WakeLock使Android应用程序保持后台唤醒
189 0
|
7月前
|
存储 机器学习/深度学习 算法
Android 应用程序通过MediaPipe 图片识别
Android 应用程序通过MediaPipe 图片识别
169 0
|
7月前
|
存储 Linux Android开发
会C/C++就可以开发Linux/Android应用程序?替代传统串口屏的Yoxios了解一下!
会C/C++就可以开发Linux/Android应用程序?替代传统串口屏的Yoxios了解一下!
141 0
|
8月前
|
Android开发
Android 应用程序一直处于竖屏模式(又称肖像模式)
Android 应用程序一直处于竖屏模式(又称肖像模式)
117 0
|
XML API 开发工具
❤️【Android精进之路-03】创建第一个Android应用程序竟然如此简单❤️
上一篇文章我们介绍了Android Studio的安装以及Android SDK的目录结构。这篇文章将介绍如何使用Android Studio创建第一个Android应用,重点介绍Android Studio的目录结构。
105 0
❤️【Android精进之路-03】创建第一个Android应用程序竟然如此简单❤️
|
存储 编解码 缓存
Android清单文件详解(三)----应用程序的根节点<application>
Android清单文件详解(三)----应用程序的根节点<application>
365 0
Android清单文件详解(三)----应用程序的根节点<application>
|
监控 Java 物联网
Android清单文件详解(二) ---- 应用程序权限声明(二)
Android清单文件详解(二) ---- 应用程序权限声明(二)
207 0
Android清单文件详解(二) ---- 应用程序权限声明(二)
|
存储 监控 Java
Android清单文件详解(二) ---- 应用程序权限声明(一)
Android清单文件详解(二) ---- 应用程序权限声明(一)
321 0
Android清单文件详解(二) ---- 应用程序权限声明(一)