zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    对象池使用时要注意几点
    Flash3D学习计划(一)——3D渲染的一般管线流程
    714. Best Time to Buy and Sell Stock with Transaction Fee
    712. Minimum ASCII Delete Sum for Two Strings
    647. Palindromic Substrings(马拉车算法)
    413. Arithmetic Slices
    877. Stone Game
    338. Counting Bits
    303. Range Sum Query
    198. House Robber
  • 原文地址:https://www.cnblogs.com/hehehaha/p/6147251.html
Copyright © 2011-2022 走看看