android异步处理Handler+Thread使用进阶(三)
2014-01-19 14:32
513 查看
关于Handler+Thread的使用终于有了一个比较完善的解决方案,自己也一直在自己的项目中使用,不断改进。这次的结构是前所未有的清新,在Activity不会再出现臃肿的代码,条理清晰。线程还是还是延续上次的设计进行集中管理。
这次的重要改动:
使用接口替代了抽象类来实现回调方法(对于java不能多继承,这无疑是个更好的设计)
接口的泛型粒度更小(原来的设计泛型是类级别,现在设计到方法级别)
新增等待提示
这次改动同样也支持Fragment,而且对同一Activity或Fragment中多个线程有更好的支持。
下个版本的计划:
添加线程的控制(大家应该注意到,线程返回一个Future对象,下次会在这上面做文章)
等待提示控制(现在提示窗口,是由现在程序自己控制,控制力度感觉不够)
这次涉及的知识主要是 接口、回调、泛型。
还是老惯例,上demo.
先是定义的一个回调接口
登录的Activity
MainActivity:
各种接口的实现类
RestImpl:
Handler类,新增了等待提示
AppHandler:
测试的javaBean
最后是布局代码:
activity_main.xml
点击下载示例demo
本人自己在项目中设计的不仅仅只有这些,还包括缓存机制、异常处理机制等。这种线程的集中管理方式对其他设计有很好的支持。我也会在项目结束后和大家分享项目的整体设计。
这次的重要改动:
使用接口替代了抽象类来实现回调方法(对于java不能多继承,这无疑是个更好的设计)
接口的泛型粒度更小(原来的设计泛型是类级别,现在设计到方法级别)
新增等待提示
这次改动同样也支持Fragment,而且对同一Activity或Fragment中多个线程有更好的支持。
下个版本的计划:
添加线程的控制(大家应该注意到,线程返回一个Future对象,下次会在这上面做文章)
等待提示控制(现在提示窗口,是由现在程序自己控制,控制力度感觉不够)
这次涉及的知识主要是 接口、回调、泛型。
还是老惯例,上demo.
先是定义的一个回调接口
package com.sc.htdemo.app; /** * @author SunnyCoffee * @date 2013-9-30 * @version 1.0 * @desc 回调接口 */ public interface AppCallback<T> { public void call(T result); }
登录的Activity
MainActivity:
package com.sc.htdemo; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import com.sc.htdemo.app.AppCallback; import com.sc.htdemo.app.RestImpl; import com.sc.htdemo.bean.User; public class MainActivity extends Activity implements OnClickListener, AppCallback<User> { private EditText nameEt; private EditText pwdEt; private Button loginBtn; private TextView resultTv; private User user; private RestImpl rest = new RestImpl(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); } private void initView() { nameEt = (EditText) findViewById(R.id.nameEt); pwdEt = (EditText) findViewById(R.id.pwdEt); loginBtn = (Button) findViewById(R.id.loginBtn); resultTv = (TextView) findViewById(R.id.resultTv); loginBtn.setOnClickListener(this); } @Override public void onClick(View v) { String name = nameEt.getText().toString(); String pwd = pwdEt.getText().toString(); user = new User(); user.setName(name); user.setPwd(pwd); // 这里传递两个this,一个是context,一个是接口实例。 rest.login(this, this, user); } @Override public void call(User result) { String text = "username:" + result.getName() + "\n" + "photo:" + result.getPhoto() + "\n" + "sign:" + result.getSign(); resultTv.setText(text); } }当类中有多个线程时,以如下方式调用接口
rest.login(this, new AppCallback<User>() { @Override public void call(User result) { } }, user);
各种接口的实现类
RestImpl:
package com.sc.htdemo.app; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import android.content.Context; import android.os.Handler; import android.os.Message; import com.sc.htdemo.bean.User; /** * @Author SunnyCoffee * @Date 2013-7-29 * @version 1.0 * @Desc 获取数据的接口实现类。(为了清晰,Rest接口就没再写) */ public class RestImpl { private ExecutorService service = RestHelper.getThreadPool(); /** * 用户登录 * * @param context * @param callback * @param user * @return 可以用来终止线程 */ public <T> Future<?> login(final Context context, final AppCallback<T> callback, final User user) { // 创建一个handler和一个Thread final AppHandler<T> handler = new AppHandler<T>(context, callback); Runnable task = new Runnable() { @Override public void run() { // 模拟网络延时,服务器返回数据 try { String name = user.getName(); String pwd = user.getPwd(); Thread.sleep(3000); User u = new User(); u.setSign("hello,大家好,我是" + name); u.setName(name); u.setPwd(pwd); u.setPhoto("http://www.isunnycoffee.com"); sendData(handler, u);// 通过handler传递服务器返回的数据 } catch (InterruptedException e) { e.printStackTrace(); } } }; return service.submit(task); } private void sendData(Handler handler, Object obj) { Message msg = handler.obtainMessage(); msg.obj = obj; handler.sendMessage(msg); } } // 提供线程池 final class RestHelper { private static final int THREAD_POOL_SIZE = 5; private static ExecutorService service = null; private RestHelper() { } public static ExecutorService getThreadPool() { if (service == null) service = Executors.newFixedThreadPool(THREAD_POOL_SIZE); return service; } }
Handler类,新增了等待提示
AppHandler:
package com.sc.htdemo.app; import android.app.ProgressDialog; import android.content.Context; import android.os.Handler; import android.os.Message; /** * @Author SunnyCoffee * @Date 2013-7-29 * @version 1.0 * @Desc Handler。获得返回值,通过执行回调方法更新UI */ public class AppHandler<T> extends Handler { private Context context; private AppCallback<T> callback; private ProgressDialog dialog;// 等待窗口 public AppHandler(Context context, AppCallback<T> callback) { this.context = context; this.callback = callback; showWaiting(); } @Override public void handleMessage(Message msg) { closeWaiting(); if (msg.obj == null) return; @SuppressWarnings("unchecked") T result = (T) msg.obj; if (callback != null) { callback.call(result); } } private void showWaiting() { dialog = new ProgressDialog(context); dialog.setCancelable(true); dialog.setMessage("waiting..."); dialog.setCancelable(false); dialog.show(); } private void closeWaiting() { if (dialog != null) { dialog.dismiss(); } } }
测试的javaBean
package com.sc.htdemo.bean; /** * @author SunnyCoffee * @date 2013-9-30 * @version 1.0 * @desc userbean */ public class User { private int id; private String name; private String pwd; private String photo;// 头像图片的url private String sign;// 个性签名 public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } public String getPhoto() { return photo; } public void setPhoto(String photo) { this.photo = photo; } public String getSign() { return sign; } public void setSign(String sign) { this.sign = sign; } }
最后是布局代码:
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <EditText android:id="@+id/nameEt" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="10dp" android:hint="Enter the username" /> <EditText android:id="@+id/pwdEt" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="10dp" android:hint="Enter the password" android:inputType="textPassword" /> <Button android:id="@+id/loginBtn" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="10dp" android:text="Login" /> <TextView android:id="@+id/resultTv" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="10dp" android:gravity="left" /> </LinearLayout>
点击下载示例demo
本人自己在项目中设计的不仅仅只有这些,还包括缓存机制、异常处理机制等。这种线程的集中管理方式对其他设计有很好的支持。我也会在项目结束后和大家分享项目的整体设计。
相关文章推荐
- 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界面