参考文献:Android多线程(IntentService篇)

1. 前言

例如上传下载等操作原则上要尽可能的交给 Service 去做,原因就是上传等过程中用户可能会有将应用至于后台,那这时候 Activity 很有可能就被杀死了。如果担心 Service 被杀死还能通过 startForeground 提升优先级。
但在 Service 里需要开启线程才能进行耗时操作,自己管理 Service 与线程听起来就不像一个优雅的做法,此时就可以用到 Android 提供的一个类,IntentService。

2. 基础使用

  1. 创建 MyIntentService 继承 IntentService,并在 onHandlIntent() 中实现耗时操作
  2. Activity 注册并启动广播监听耗时操作完成事件,如更新 UI
  3. Activity 中启动 MyIntentService
  4. 记得 IntentServic 也是 Service 要注册
public class MyIntentService extends IntentService {
    private static final String ACTION_UPLOAD_IMG = "com.qit.action.UPLOAD_IMAGE";
    public static final String EXTRA_IMG_PATH = "com.qit.extra.IMG_PATH";

    // 上传图片,回调 onHandleIntent 方法。
    public static void startUploadImg(Context context, String path) {
        Intent intent = new Intent(context, MyIntentService.class);
        intent.setAction(ACTION_UPLOAD_IMG);
        intent.putExtra(EXTRA_IMG_PATH, path);
        context.startService(intent);
    }


    public MyIntentService() {
        super("MyIntentService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        if (intent != null) {
            final String action = intent.getAction();
            if (ACTION_UPLOAD_IMG.equals(action)) {
                final String path = intent.getStringExtra(EXTRA_IMG_PATH);
                handleUploadImg(path);
            }
        }
    }

    private void handleUploadImg(String path) {
        try {
            //模拟上传耗时
            Thread.sleep(((long) (Math.random() * 3000)));

            Intent intent = new Intent(MainActivity.UPLOAD_RESULT);
            intent.putExtra(EXTRA_IMG_PATH, path);
            // 上传完成发送广播
            sendBroadcast(intent);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
public class MainActivity extends AppCompatActivity {
    public static final String UPLOAD_RESULT = "com.qit.UPLOAD_RESULT";

    private LinearLayout ll;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ll = (LinearLayout) findViewById(R.id.ll);
        findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 添加上传任务
                addTask();
            }
        });
        // 注册接收器
        IntentFilter filter = new IntentFilter();
        filter.addAction(UPLOAD_RESULT);
        registerReceiver(uploadImgReceiver, filter);
    }

    // 操作完成广播接收器
    private BroadcastReceiver uploadImgReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction() == UPLOAD_RESULT) {
                String path = intent.getStringExtra(MyIntentService.EXTRA_IMG_PATH);
                handleResult(path);
            }

        }
    };

    // 处理结果
    private void handleResult(String path) {
        TextView tv = (TextView) ll.findViewWithTag(path);
        tv.setText(path + " upload success ~~~ ");
    }

    int i = 0;

    public void addTask() {
        //模拟路径
        String path = "/sdcard/imgs/" + (++i) + ".png";
        // 开启 service
        MyIntentService.startUploadImg(this, path);

        TextView tv = new TextView(this);
        ll.addView(tv);
        tv.setText(path + " is uploading ...");
        tv.setTag(path);
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(uploadImgReceiver);
    }
}