小弟新手一枚,我先来说说我自己在项目中的做法。因为小弟只有JAVAWEB的基础所以只能使用线程池来处理线程之间的切换

1.为了使APP不出现卡顿和内存的低消耗。我是用了synchronized 和用一个Map 来限定每次只能运行一条子线程,Map 键:TAG 线程任务标记 、值:FutureTask线程任务,

2.当然线程之间的切换仍然还是使用handle,只是在等待分线程执行完,当然分线程也会由限定时间。

下面来看看代码:

public class OCThreadExecutor extends ThreadPoolExecutor {

private Map runnableMap;

public OCThreadExecutor(int maxRunningThread, String poolName) {

super(maxRunningThread, maxRunningThread, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(), 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{

public static final String TAG = "GetArtclesThread";

private OnArtcleLoadCallback onArtcleLoadCallback;

private boolean needToCacheImage;

private ArrayList 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线程显示文章。

目前只知道这种方式,不知道大家有没有更好的方法?  求教

android判断主线程_android中从子线程切换到主线程,但是显得代码很臃肿,请教大牛是怎么自定义的?...相关推荐

  1. c# 火狐浏览器怎么嵌入窗体中_C#WinForm窗体内Panel容器中嵌入子窗体、程序主窗体设计例子...

    C#WinForm父级窗体内Panel容器中嵌入子窗体.程序主窗体设计例子 在项目开发中经常遇到父级窗体嵌入子窗体所以写了一个例子程序,顺便大概划分了下界面模块和配色,不足之处还望指点 主窗体窗体采用 ...

  2. main线程 子线程 顺序_在主线程main中开启子线程thread示例

    主线程中开启子线程代码实例: 创建CancleThread类 继承 Thread,对run()方法进行重写代码实例: class CancleThread extends Thread { priva ...

  3. android 滑动取值_Android中滑屏实现

    前言:  虽然本文标题的有点标题党的感觉,但无论如何,通过这篇文章的学习以及你自己的实践认知,写个简单的滑屏小 Demo还是justso so的. 友情提示: 在继续往下面读之前,希望您对以下知识点有 ...

  4. java android消息推送_Android中使用socket通信实现消息推送的方法详解

    原理最近用socket写了一个消息推送的demo,在这里和大家分享一下. 主要实现了:一台手机向另外一台手机发送消息,这两台手机可以随时自由发送文本消息进行通信,类似我们常用的QQ. 效果图: 原理: ...

  5. android id 重名_android 中Xml里面的id重名问题

    今天在做项目的时候,居然发现@+id 居然可以重名,而且 情况一:同个一个Xml文件中的同名 在同个一个Xml文件的中若同名了,则前一个有效,而后一个无效,即后一个Null掉.如: android:i ...

  6. android id 重名_android 中不同的Xml中id可以重名吗?

    今天在做项目的时候,居然发现@+id 居然可以重名,而且 情况一:同一个Xml文件中的同名 在同一个Xml文件的中若同名了,则前一个有效,而后一个无效,as会报异常.如: android:id=&qu ...

  7. android mqtt详解_Android 中MQTT协议的使用

    前言 项目中有用到mqtt,碰巧没人负责这一块,所以毛遂自荐就看了一波,下面是一些简单的使用记录,写得不好,仅供参考.若没有mqtt服务器的朋友,建议先建一个mqtt服务,不然看不到效果. 什么是Mq ...

  8. android 调用java类_Android中在WebView里实现Javascript调用Java类的方法

    搜索热词 为了方便网页和Android应用的交互,Android系统提供了WebView中JavaScript网页脚本调用Java类方法的机制.只要调用addJavascriptInterface方法 ...

  9. android打开视频噔_Android中三种视频的播放

    在Android中,我们有三种方式来实现视频的播放: 1.使用其自带的播放器.指定Action为ACTION_VIEW,Data为Uri,Type为其MIME类型. 2.使用VideoView来播放. ...

最新文章

  1. 用Asp.net实现简单的文字水印
  2. R3LIVE:一个实时鲁棒、带有RGB颜色信息的激光雷达-惯性-视觉紧耦合系统(香港大学)...
  3. 【转】DNS查询过程
  4. 工作五年,后面四年重复着第一年的活儿?
  5. 第八章 神经网络表示-机器学习老师板书-斯坦福吴恩达教授
  6. html 查询表单,如何让我的HTML表单查询适用于所有表单元素?
  7. FFMPEG avformat_open_input
  8. 数据库的日常管理经验浅谈
  9. wamp无法使用php,使用wamp无法访问www中的php文件
  10. c++ 数组的输入遇到特定字符停止输入_滑动窗口思维--挑战“无重复字符的最长子串”
  11. 计算机主机硬件图片,电脑主机内部有哪些硬件
  12. igmp是哪个层协议_通俗易懂网络协议(IP)
  13. spool导出姓名中文乱码_MySQL不同字符集转化标准—7步实现,杜绝乱码!
  14. dataguard switchover的自动化脚本实现
  15. Python3爬虫入门之beautifulsoup库的使用
  16. 厦门IT公司名单及联系方式
  17. linux 目录配额,详细讲解linux磁盘配额之Quota命令
  18. 简单excel饼状图怎么做,bi工具怎么做饼状图
  19. 这些旅游类短视频账号在快手涨粉的总结
  20. TFTP文件传输协议

热门文章

  1. git撤销分支上代码的修改
  2. Django中间件与python日志模块 介绍
  3. python简单练习 -统计文本词频并用柱状图显示
  4. 把 charles,Fiddler 证书安装到安卓根目录,解决安卓微信 7.0 版本以后安装证书也无法抓包问题,需要 root
  5. Java加密与解密的艺术~数字签名~DSA实现
  6. java运行命令解释
  7. linux 网卡 巨帧,Linux Kernel e1000e驱动巨型帧处理绕过安全检查漏洞
  8. python追加_如何在Python中追加文件?
  9. git灰度发布版本_Git发布2.30版本
  10. java 指代对象_java-This的理解