小弟新手一枚,我先来说说我自己在项目中的做法。因为小弟只有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中从子线程切换到主线程,但是显得代码很臃肿,请教大牛是怎么自定义的?…-编程知识网创作挑战赛新人创作奖励来咯,坚持创作打卡瓜分现金大奖