android异步处理Handler+Thread使用进阶(二)
2014-01-19 15:08
513 查看
在上篇文章《android异步处理Handler+Thread使用进阶》中提到的问题做相应的方案,很多地方已经优化,这次的结构更加合理。
文章涉及的几个知识点又必须要了解,如泛型,继承,抽象方法,单例等。
设计思想和上次一样,不同的是这次每一个线程对应一个Handler,handler和线程服务都不再使用static。基类设置抽象方法,即回调方法。同时设置泛型,来确定回调方法的返回值。
同时支持Fragment。
先看个登录的例子:
MainActivity:
一句话执行登录操作,一句话更新UI!
BaseActivity:
Rest:
Rest里提供各种接口,如login(),regist(),getGoodList()等等。每个接口方法里都创建一个Handler和一个Runnable。Handler用来接收服务器返回值,调用回调方法;Runable丢进线程池执行联网、解析等耗时操作。
AppHandler:
这里增加了对Fragment的支持。对应的Fragment的基类:
BaseFmt,同activity的基类一样:
不足之处:这里只是针对一个Activity中有一个子线程操作的情况,当同时存在多个子线程的时候可以通过修改抽象call(T result,int which)来区分多个线程的返回值。
不过这又会引起新的问题:当多个线程的返回值的类型不一致的时候,泛型的作用就失效了,还是要进行强制类型转换。
这个设计还没有正式用在我的项目中,这还都在测试阶段,下一步我会试着去掉泛型,并添加对多个线程的支持。
改进方案参考:
文章涉及的几个知识点又必须要了解,如泛型,继承,抽象方法,单例等。
设计思想和上次一样,不同的是这次每一个线程对应一个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; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv = (TextView) findViewById(R.id.tv); getRest().login(this, "zhangsan", "123");//这里执行登录 } //回调方法。登录完后执行,更新UI。 @Override public 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和一个Thread final AppHandler<T> handler = new AppHandler<T>(context); Runnable thread = new Runnable() { @Override public 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; } @Override public void handleMessage(Message msg) { if (msg.obj == null) return; @SuppressWarnings("unchecked") T result = (T) msg.obj; //这里判断一下Activity是否已经destroy if (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使用进阶(三)
相关文章推荐
- android异步处理Handler+Thread使用进阶(三)
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面 .
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面 .
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面
- Android 进阶15:HandlerThread 使用场景及源码解析
- [转]Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面
- Android异步处理系列文章四篇之一使用Thread+Handler实现非UI线程更新UI界面