android异步处理Handler+Thread使用进阶(二)
16lz
2021-01-25
在上篇文章《android异步处理Handler+Thread使用进阶》中提到的问题做相应的方案,很多地方已经优化,这次的结构更加合理。
文章涉及的几个知识点又必须要了解,如泛型,继承,抽象方法,单例等。
设计思想和上次一样,不同的是这次每一个线程对应一个Handler,handler和线程服务都不再使用static。基类设置抽象方法,即回调方法。同时设置泛型,来确定回调方法的返回值。
同时支持Fragment。
先看个登录的例子:
MainActivity:
package com.sc.htdemo;import android.os.Bundle;import android.widget.TextView;public class MainActivity extends BaseActivity<String> {private TextView tv;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);tv = (TextView) findViewById(R.id.tv);getRest().login(this, "zhangsan", "123");//这里执行登录}//回调方法。登录完后执行,更新UI。@Overridepublic void call(String result) {tv.setText(result);}}
一句话执行登录操作,一句话更新UI!
BaseActivity:
package com.sc.htdemo;import android.app.Activity;import com.sc.htdemo.app.Rest;/** * @author SunnyCoffee * @Date 2013-7-18 * @version 1.0 * @Desc Activity的基类,泛型表示回调方法返回的数据类型 */// 使用泛型,这样返回类型更精确public abstract class BaseActivity<T> extends Activity {/** * 获取服务对象 * * @return */public Rest<T> getRest() {return new Rest<T>();}/** * 这是个回调方法,线程的内容执行完后进行回调。 * * @param result */public abstract void call(T result);}
Rest:
package com.sc.htdemo.app;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import android.os.Handler;import android.os.Message;import com.google.gson.Gson;import com.sc.htdemo.BaseActivity;/** * @Author SunnyCoffee * @Date 2013-7-29 * @version 1.0 * @Desc 获取数据的接口类 */public class Rest<T> {private Gson gson = RestHelper.getGson();private ExecutorService service = RestHelper.getThreadPool();/** * 用户登录 * * @param context * @param acount * @param pwd */public void login(final BaseActivity<T> context, final String acount,final String pwd) {//创建一个handler和一个Threadfinal AppHandler<T> handler = new AppHandler<T>(context);Runnable thread = new Runnable() {@Overridepublic void run() {// 这里进行联网解析操作// String json = HttpConn.get(context, acount);// Test test = gson.fromJson(json, Test.class);sendData(handler, "result");}};service.execute(thread);}private void sendData(Handler handler, Object obj) {Message msg = handler.obtainMessage();msg.obj = obj;handler.sendMessage(msg);}}//这里使用单例。提供一个线程池和一个gson对象final class RestHelper {private static final int THREAD_POOL_SIZE = 5;private static ExecutorService service = null;private static Gson gson = null;private RestHelper() {}public static ExecutorService getThreadPool() {if (service == null)service = Executors.newFixedThreadPool(THREAD_POOL_SIZE);return service;}public static Gson getGson() {if (gson == null)gson = new Gson();return gson;}}
Rest里提供各种接口,如login(),regist(),getGoodList()等等。每个接口方法里都创建一个Handler和一个Runnable。Handler用来接收服务器返回值,调用回调方法;Runable丢进线程池执行联网、解析等耗时操作。
AppHandler:
package com.sc.htdemo.app;import android.os.Handler;import android.os.Message;import com.sc.htdemo.BaseActivity;import com.sc.htdemo.BaseFmt;/** * @Author SunnyCoffee * @Date 2013-7-29 * @version 1.0 * @Desc Handler。获得返回值,通过执行回调方法更新UI */public class AppHandler<T> extends Handler {private BaseActivity<T> act;private BaseFmt<T> fmt;public AppHandler(BaseActivity<T> act) {this.act = act;}public AppHandler(BaseFmt<T> fmt) {this.fmt = fmt;}@Overridepublic void handleMessage(Message msg) {if (msg.obj == null)return;@SuppressWarnings("unchecked")T result = (T) msg.obj;//这里判断一下Activity是否已经destroyif (act != null && !act.isFinishing())act.call(result);// 执行回调方法else if (fmt != null && fmt.isVisible())fmt.call(result);}}
这里增加了对Fragment的支持。对应的Fragment的基类:
BaseFmt,同activity的基类一样:
package com.sc.htdemo;import android.support.v4.app.Fragment;import com.sc.htdemo.app.Rest;/** * @author SunnyCoffee * @create 2013-8-6 * @version 1.0 * @desc Fragment的基类 */public abstract class BaseFmt<T> extends Fragment {/** * 获取服务对象 * * @return */public Rest<T> getRest() {return new Rest<T>();}/** * 这是个回调方法,线程的内容执行完后进行回调 * * @param result */public abstract void call(T result);}
不足之处:这里只是针对一个Activity中有一个子线程操作的情况,当同时存在多个子线程的时候可以通过修改抽象call(T result,int which)来区分多个线程的返回值。
不过这又会引起新的问题:当多个线程的返回值的类型不一致的时候,泛型的作用就失效了,还是要进行强制类型转换。
这个设计还没有正式用在我的项目中,这还都在测试阶段,下一步我会试着去掉泛型,并添加对多个线程的支持。
改进方案参考:
android异步处理Handler+Thread使用进阶(三)
更多相关文章
- 高级Redis应用进阶课 一站式Redis解决方案
- Android新提供的测试框架支持库学习 && Testing Support Library
- Android:在子线程中更新UI,解析异步消息处理机制(Handler)
- android客户端—AsyncTask的使用
- 详解Android使用OKHttp3实现下载(断点续传、显示进度)
- Android(安卓)去掉系统默认提示音、移除音量调节的进度条、增加
- Android(安卓)绑定类型服务---简介
- Android引入外部自定义特殊字体的方法
- android开发之Android(安卓)Interface Definition Language(AIDL)