Android组件——Service

一、多任务实现的基本原理

  • 默认情况下,同一个应用程序的所有组件都运行在同一个进程中,大部分应用程序是按这种方式运行的
  • 在具体应用中需要通过设置mainifest文件中组件的android:process属性,是该组件运行在不同的进程中
  • 元素也支持android:process属性,用于指定所有组件的默认进程

进程的层次结构

  • 前台进程
  • 可见进程
  • 服务进程
  • 后台进程
  • 空进程

安卓中的线程

Android是单线程的模型,我们创建的Service、Activity均是在一个主线程处理,即UI线程。应用程序默认是一个单任务单线程的程序
UI线程运行着许多重要的逻辑,如事件处理、用户输入输出、Service等
Android组件——Service_第1张图片
虽然我们感觉上许多任务在同时运行,但实际上却是通过调度算法进行的串行运行。
因此,我们编写的代码实际上是穿插在主线程运行的,如果我们插入的代码比较耗时,就会阻塞UI线程上其他逻辑的执行,从而造成页面卡顿。如果卡顿超过5秒,系统就会触发ANR错误。所以,执行耗时的操作,需要创建新的线程执行。

注意:Android中的UI toolkit不是线程安全的,不能在非UI线程更新UI,所有对界面的更新都必须在UI线程执行

多任务的实现原理

  • Android中的两种线程:UI主线程和工作线程
  • 通常把耗时的操作放到工作线程执行,操作完成后,再通知主线程做出相应的响应

AsyncTask

  • AsyncTask是android提供的异步处理的辅助类,可以实现耗时任务在其他线程处理,而处理结果在UI线程执行
  • 屏蔽了线程和Handler,进行了高度封装
  • 具有特定功能的回调方法:
    onPreExecute():预处理方法
    publishProgress():更新进度方法
    onPostExecute():返回结果的方法
    

示例代码

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private Button btn;

    private TextView txt;

    private ProgressBar progress;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn = findViewById(R.id.btn);
        txt = findViewById(R.id.txt);
        progress = findViewById(R.id.progress_horizontal);
        btn.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.btn:
                progress.setVisibility(ProgressBar.VISIBLE);
                MyAsyncTask myAsyncTask = new MyAsyncTask();
                myAsyncTask.execute(1000);
                break;
        }
    }


    private class MyAsyncTask extends AsyncTask<Integer, Integer, String> {

        private final static String TAG = "MyAsyncTask";

        public MyAsyncTask() {
            super();
        }

        @Override
        protected void onPreExecute() {
            Log.d(TAG, "onPreExecute, thread id is: " + Thread.currentThread().getId());
        }

        @Override
        protected void onPostExecute(String s) {
            Log.d(TAG, "onPostExecute, thread id is: " + Thread.currentThread().getId());
            txt.setText(s);
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            Log.d(TAG, "onProgressUpdate, thread id is: " + Thread.currentThread().getId());
            progress.setProgress(values[0]);
        }

        @Override
        protected String doInBackground(Integer... integers) {
            Log.d(TAG, "doInBackground, thread id is: " + Thread.currentThread().getId());
            for (int i = 0; i <= 10; i++) {
                publishProgress(i*10);
                try {
                    Thread.sleep(integers[0]);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            return "更新完成";
        }
    }
}

Handler机制

Handler是通过消息队列进行通信的机制

  • Handler:负责消息的发送和处理,通过它实现工作线程和UI线程的消息通讯
  • Looper:负责管理线程的消息队列和消息循环
  • Message:线程间通讯的消息载体,Message充当消息封装的功能
  • MessageQueue:消息队列,先进先出,保存待线程处理的消息

Looper类
Looper类是android系统封装消息循环和消息队列的一个类,线程可以通过Looper对象读写某个消息队列

	Looper.myLooper():获得当前线程的Looper对象
	Looper.getMainLooper():获得当前进程的主线程的Looper对象
	Looper.prepare():创建消息队列
	Looper.loop():进入消息循环

二、Service

Service是一个能够在后台执行长时间运行的操作应用程序组件,不提供用户界面,应用在后台启动一个Service运行,即使用户切换到另一个应用此Service业务继续运行

特点

  • 无法与用户直接交互
  • 必须由用户或其他程序启动
  • 优先级介于前台应用和后台应用之间

Service具有自己的生命周期。Service生命周期与Activity生命周期是分离的,当Activity被暂停、销毁时,Service组件还可以继续处理其他任务

安卓支持服务的原因:

  • 允许执行后台任务
  • 实现同一设备上应用之间的跨进程通信

创建方式

  • 自启动方式:startService
  • 绑定方式:bindService
    Android组件——Service_第2张图片

自启动方式

绑定方式

Android组件——Service_第3张图片

服务的生命周期

Android组件——Service_第4张图片

创建自启动类型服务

  • 通过startService()方法创建一个启动型的Service
  • 启动服务时需要通过intent显示或者隐式启动,Intent可以携带一部分数据,在Service的onStartCommand中可以使用其数据
  • 默认启动的服务存在于主线程中,会导致主线程阻塞,故通常采用新线程模式启动服务
    继承Service
    继承IntentService

IntentService

IntentService是Service的子类,用于处理异步请求。大多数服务不需要处理多个请求,所以用IntentService是很好的选择。
客户端可以通过startService(Intent)方法传递请求Intent信息
IntentService实际上是实际上是

你可能感兴趣的:(android,ui)