• Android Priority Job Queue (Job Manager)(一)


    

    Android Priority Job Queue (Job Manager)(一)


    一、为什么要引入Android Priority Job Queue (Job Manager)?
    如今的APP开发中,几乎绝大多数APP没有不需要后台线程操作和运行的任务,Android平台自身提供了一些后台线程的编程实现模型和API。比如常见的主流后台+线程处理方式:
    A、 AsyncTask,
    B、 Loaders,
    C、 以及更复杂的Service组合线程池(Thread Pool),
    D、Java的Thread结合Handler。
    等等。
    但是以上方式的问题很多,尤其是在耦合到Android本身的Activity或Fragment生命周期时候,要处理各种实际的场景,还有就是当在线程操作中如果处理失败,又该怎么办?有些情况,比如当用户在WIFI或者2G/3G/4G不同网络时候的不同网络加载策略。假设用户在发送一条消息到服务器,但是在线程发送过程中网络中断,在一定时延后网络又接通,此时线程又该如何决定发送任务的再次处理?如果使用Java Thread,Android本身又不允许在主线程外更新UI。如果使用Service,那么还要解决Service和,等等等诸如此类问题全部丢到线程中处理,将会额外但又不得不处理多种状态情况。
    所以,为解决上述问题,就需要引入一种相对完善、可以解决后台+线程的简单易用的线程任务调度管理框架,为此引入Android Priority Job Queue (Job Manager)。
    Android Priority Job Queue (Job Manager)是github上的一个Android开源项目,项目主页是:https://github.com/yigit/android-priority-jobqueue
    Android Priority Job Queue (Job Manager)在其项目主页有完整的项目研究背景和作用,简单概括起来就是简化了Android涉及到的后台线程编程开发工作,使得开发者从后台线程繁琐的开发和代码维护中解脱出来,专注于业务逻辑。

    二、Android Priority Job Queue (Job Manager)使用简介。

    (1) Android Priority Job Queue (Job Manager)首先需要初始化和配置,在初始化和配置阶段,Android Priority Job Queue (Job Manager)类似Java线程池,写一个MyApplication继承自
    Android Application,在此完成初始化。MyApplication.java:

    package zhangphil.app;
    
    import android.app.Application;
    import android.util.Log;
    
    import com.birbit.android.jobqueue.JobManager;
    import com.birbit.android.jobqueue.config.Configuration;
    import com.birbit.android.jobqueue.log.CustomLogger;
    
    /**
     * Created by Phil on 2016/10/9.
     */
    public class MyApplication extends Application {
        private JobManager jobManager;
    
        private static MyApplication instance;
    
        public MyApplication() {
            instance = this;
        }
    
        public static MyApplication getInstance() {
            return instance;
        }
    
        @Override
        public void onCreate() {
            super.onCreate();
            getJobManager();// ensure it is created
        }
    
        public synchronized JobManager getJobManager() {
            if (jobManager == null) {
                configureJobManager();
            }
    
            return jobManager;
        }
    
        private void configureJobManager() {
            Configuration.Builder builder = new Configuration.Builder(this)
                    .customLogger(new CustomLogger() {
                        private static final String TAG = "zhangphil job";
    
                        @Override
                        public boolean isDebugEnabled() {
                            return true;
                        }
    
                        @Override
                        public void d(String text, Object... args) {
                            Log.d(TAG, String.format(text, args));
                        }
    
                        @Override
                        public void e(Throwable t, String text, Object... args) {
                            Log.e(TAG, String.format(text, args), t);
                        }
    
                        @Override
                        public void e(String text, Object... args) {
                            Log.e(TAG, String.format(text, args));
                        }
    
                        @Override
                        public void v(String text, Object... args) {
    
                        }
                    })
                    .minConsumerCount(1)//always keep at least one consumer alive
                    .maxConsumerCount(3)//up to 3 consumers at a time
                    .loadFactor(3)//3 jobs per consumer
                    .consumerKeepAlive(120);//wait 2 minute
    
            jobManager = new JobManager(builder.build());
        }
    }

    实际上在自己的项目中,Android Priority Job Queue (Job Manager)的初始化工作基本上不用做修改大体按照上面的写就好了,调整的地方在于任务数量这些有关系统性能开销的地方控制。
    写完了记得要在Androidmainfest.xml写到application下面:

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="zhangphil.app">
    
        <application
            android:name=".MyApplication"
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
            <activity android:name=".MainActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>
    
    </manifest>


    (2)写一个请求的任务逻辑,这是Android Priority Job Queue (Job Manager)使用的关键地方。首先需要继承自Android Priority Job Queue (Job Manager)得Job类,我写了一个测试的MyJob类,在此类中用于完成后台+线程的任务操作,Android Priority Job Queue (Job Manager)的Job有些类似于Java的Runnable,可以比照Java的Runnable理解Android Priority Job Queue (Job Manager)的Job。耗时线程任务在onRun里面做,MyJob.java:

    package zhangphil.app;
    
    import android.os.SystemClock;
    import android.support.annotation.NonNull;
    import android.support.annotation.Nullable;
    import android.util.Log;
    
    import com.birbit.android.jobqueue.Job;
    import com.birbit.android.jobqueue.Params;
    import com.birbit.android.jobqueue.RetryConstraint;
    
    /**
     * Created by Phil on 2016/10/9.
     */
    public class MyJob extends Job {
    
        private String tag;
    
        public MyJob(String tag) {
            super(new Params(500).requireNetwork().persist().groupBy(tag));
            this.tag = tag;
            Log.d(tag, "初始化");
        }
    
        @Override
        public void onAdded() {
            Log.d(tag, "添加任务");
        }
    
        //在这里面放置耗时的后台线程化任务
        @Override
        public void onRun() throws Throwable {
            Log.d(tag, "开始运行...");
    
            int i = 0;
            while (true) {
                i++;
    
                SystemClock.sleep(2000);
                Log.d(tag, String.valueOf(i));
                if (i == 10)
                    break;
            }
    
            Log.d(tag, "完成");
        }
    
        @Override
        protected RetryConstraint shouldReRunOnThrowable(@NonNull Throwable throwable, int runCount, int maxRunCount) {
            // An error occurred in onRun.
            // Return value determines whether this job should retry or cancel. You can further
            // specify a backoff strategy or change the job's priority. You can also apply the
            // delay to the whole group to preserve jobs' running order.
    
            Log.d(tag, "runCount:" + runCount);
    
            return RetryConstraint.createExponentialBackoff(runCount, 1000);
        }
    
        @Override
        protected void onCancel(int cancelReason, @Nullable Throwable throwable) {
    
        }
    }
    


    (3)测试的MainActivity.java:

    package zhangphil.app;
    
    import android.app.Activity;
    import android.os.Bundle;
    
    import com.birbit.android.jobqueue.JobManager;
    
    public class MainActivity extends Activity {
    
        private JobManager jobManager;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            //setContentView(R.layout.activity_main);
    
            jobManager=MyApplication.getInstance().getJobManager();
    
            jobManager.addJobInBackground(new MyJob("任务1")); //启动任务,跑!
            //jobManager.addJobInBackground(new MyJob("任务2"));
            //jobManager.addJobInBackground(new MyJob("任务3"));
            //jobManager.addJobInBackground(new MyJob("任务4"));
            //jobManager.addJobInBackground(new MyJob("任务5"));
            //jobManager.addJobInBackground(new MyJob("任务6"));
        }
    }
    


    附录我写的Android线程相关文章:
    【1】《Java线程池:ExecutorService,Executors》链接地址:http://blog.csdn.net/zhangphil/article/details/43898637 
    【2】《Java线程池及Future、Callable获得线程返回结果【Java线程池系列2】》链接地址:http://blog.csdn.net/zhangphil/article/details/49701219
    【3】《Java线程池之FutureTask【Java线程池系列3】》链接地址:http://blog.csdn.net/zhangphil/article/details/49702751

  • 相关阅读:
    ArrayList 和 LinkList 的区别
    fork()相关的源码解析
    http协议状态码及其意义
    数据库的死锁相关知识
    JDBC事务的相关知识
    请求http页面的相关过程
    static 关键字的作用
    计算机网络网络层的IP地址划分及子码
    文件的相关操作.
    set集合和深浅拷贝
  • 原文地址:https://www.cnblogs.com/hehehaha/p/6147251.html
Copyright © 2020-2023  润新知