黑马程序员-多线程-在android开发中经常会遇到从子线程切换到主线程,但是频繁地切换会使代码变得很臃肿,也不好维护,想请教一下各位大牛都是怎么处理的?
2016-06-24 20:16
856 查看
------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------
小弟新手一枚,我先来说说我自己在项目中的做法。因为小弟只有JAVAWEB的基础所以只能使用线程池来处理线程之间的切换
1.为了使APP不出现卡顿和内存的低消耗。我是用了synchronized 和用一个Map 来限定每次只能运行一条子线程,Map 键:TAG 线程任务标记 、值:FutureTask线程任务,
2.当然线程之间的切换仍然还是使用handle,只是在等待分线程执行完,当然分线程也会由限定时间。
下面来看看代码:
以上是自定义线程池,带参的构造方法;
重点来了:
如果没有将执行该任务,且添加进Map
下面是得到URL访问网络:
任务在UI线程中运行,知道任务完成,这是最让我纠结的地方,但是在项目中有没有出现过问题,可能是我现在的访问量不大吧!!
下面是一个获取项目文章的线程方法:
下载文章线程:
这是一个获取文章的任务,这个任务会在线程池中执行,在回调方法中会先执行请求文章,当获取文章完成之后才会去UI线程显示文章。
目前只知道这种方式,不知道大家有没有更好的方法? 求教
小弟新手一枚,我先来说说我自己在项目中的做法。因为小弟只有JAVAWEB的基础所以只能使用线程池来处理线程之间的切换
1.为了使APP不出现卡顿和内存的低消耗。我是用了synchronized 和用一个Map 来限定每次只能运行一条子线程,Map 键:TAG 线程任务标记 、值:FutureTask线程任务,
2.当然线程之间的切换仍然还是使用handle,只是在等待分线程执行完,当然分线程也会由限定时间。
下面来看看代码:
public class OCThreadExecutor extends ThreadPoolExecutor { private Map<String,FutureTask> runnableMap; public OCThreadExecutor(int maxRunningThread, String poolName) { super(maxRunningThread, maxRunningThread, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), new OCThreadFactory(poolName)); runnableMap = new HashMap<>(); }
以上是自定义线程池,带参的构造方法;
static class OCThreadFactory implements ThreadFactory { private final String name; public OCThreadFactory(String name) { this.name = name; } public String getPoolName() { return name; } @Override public Thread newThread(@NonNull Runnable r) { return new OCThread(r, name); } } static class OCThread extends Thread { public OCThread(Runnable runnable, String name) { super(runnable, name); setName(name); } @Override public void run() { android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND); super.run(); } }实现线程工厂;
重点来了:
/** * 执行任务 * @param task 任务对象 * @param tag 任务唯一TAG */ public void submit(FutureTask task , String tag){ synchronized (this){ //执行线程 if ( !runnableMap.containsKey(tag) ){ //如果池内没有相同的任务则可以执行 Log.d("OCThreadExecutor", "Task submitting TAG: "+tag); runnableMap.put(tag, task); submit(task); }else{ Log.d("OCThreadExecutor", "Pool: "+((OCThreadFactory)getThreadFactory()).getPoolName()+" Same task TAG. Skipped. "+tag); } } }以上提交方法的tag值是为了唯一识别正在执行的线程,或者判断该线程有没有在执行。
如果没有将执行该任务,且添加进Map
下面是得到URL访问网络:
protected NetworkHelper() { handler = new Handler(Looper.getMainLooper()); httpClient = new OkHttpClient(); threadExecutor = new OCThreadExecutor(1,"networkTHS"); } public static NetworkHelper getInstance() { if (networkHelper == null){ networkHelper = new NetworkHelper(); } return networkHelper; } /** * UI 线程 * @param runnable 在UI线程运行的任务 */ private void runOnUIThread(@NonNull Runnable runnable){ boolean done = handler.post(runnable); while (!done){ handler = new Handler(Looper.getMainLooper()); runOnUIThread(runnable); } }
任务在UI线程中运行,知道任务完成,这是最让我纠结的地方,但是在项目中有没有出现过问题,可能是我现在的访问量不大吧!!
下面是一个获取项目文章的线程方法:
/** * 读取文章 * @param onArtcleLoadCallback 读取进度回调 * @param needToCacheImage 是否进行缓存图片网址以供主界面滚动显示 * @param args 附带的参数 */ public void loadArtcles(@Nullable OnArtcleLoadCallback onArtcleLoadCallback ,@NonNull boolean needToCacheImage ,@NonNull String[] args){ threadExecutor.submit(new FutureTask<>(new GetArtclesThread(onArtcleLoadCallback, needToCacheImage, args)),GetArtclesThread.TAG+args[2]); }
下载文章线程:
/** * 获取文章以及缓存首页滚动图片的任务 */ class GetArtclesThread implements Callable<String>{ public static final String TAG = "GetArtclesThread"; private OnArtcleLoadCallback onArtcleLoadCallback; private boolean needToCacheImage; private ArrayList<ArtclesBean> artcles = null; private String[] args; public GetArtclesThread(OnArtcleLoadCallback onArtcleLoadCallback, boolean needToCacheImage ,String[] args) { this.onArtcleLoadCallback = onArtcleLoadCallback; this.needToCacheImage = needToCacheImage; this.args = args; } @Override public String call() throws Exception { //先检查OKHttp是否有效 if (httpClient == null){ httpClient = new OkHttpClient(); } //如果参数数量大于等于4,则执行请求 if (args != null && args.length >= 4){ try { artcles = requestData(); } catch (IOException e) { Log.d(TAG, "Exception:"+e); failed(null,e); return null; } }else { failed("无效的请求参数",null); return null; } completed(); return null; }
这是一个获取文章的任务,这个任务会在线程池中执行,在回调方法中会先执行请求文章,当获取文章完成之后才会去UI线程显示文章。
目前只知道这种方式,不知道大家有没有更好的方法? 求教
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法