第一行代码-第二版(郭霖著)笔记十(Service)

目录

一、服务是什么

二、Android多线程编程

1.线程的基本用法

2.在子线程中更新UI

3.解析异步消息处理机制

4.使用AsyncTask

三、服务的基本用法

1.定义一个服务

Tips:

2.启动和停止服务

3.活动和服务进行通信

四、服务的生命周期

五、服务的更多使用技巧

1.使用前台服务

2.使用IntentService


一、服务是什么

服务依赖于创建服务时所在的应用程序进程,当某个应用程序进程被杀掉时,所有依赖于该进程的服务也会停止运行。

二、Android多线程编程

1.线程的基本用法

第一种:新建一个类继承Thread,重写父类的run()方法,启动线程就是new出该类的实例,然后调用start()方法

第二种:新建一个类实现Runnable接口,将该类的实例参数传入new Thread()中,然后调用Thread的start()方法

2.在子线程中更新UI

此处必须是RelativeLayout,如果使用LinearLayout,复现不了子线程中更新UI报的错

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="match_parent">
 <Button
 android:id="@+id/changeTextBtn"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:text="Change Text" />
 <TextView
 android:id="@+id/textView"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_centerInParent="true"
 android:text="Hello world"
 android:textSize="20sp" />
</RelativeLayout>
public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    public static final int UPDATE_TEXT = 1;

    private TextView text;

    private Handler handler = new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            switch(msg.what){
                case UPDATE_TEXT:
                    text.setText("hello");
                    break;
                default:
                    break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        text = findViewById(R.id.text_view);
        Button changeText = findViewById(R.id.change_text);
        changeText.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch(v.getId()){
            case R.id.change_text:
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        Message message = new Message();
                        message.what = UPDATE_TEXT;
                        handler.sendMessage(message);
                    }
                }).start();
        }
    }
}

3.解析异步消息处理机制

Android中的异步消息处理主要由四个部分组成:Message、Handler、MessageQueue、Looper

1.    Message
是线程之间传递的消息
2.    Handler
处理者,用于发送和处理消息
3.    MessageQueue
消息队列,用于存放所有通过Handler发送的消息。每个线程中只会有一个MessageQueue对象。
4.    Lopper
调用Lopper的loop()方法后,就会进入到MeaageQueue中,每当发现MessageQueue存在一条消息,将会将它取出并传递到Handler的handleMessage()方法中。每个线程也只会有一个Lopper对象。

异步消息处理的核心思想:

一条Meaage从子线程进入到了主线程

4.使用AsyncTask

AsyncTask是一个抽象类,继承的时候要为AsyncTest类指定3个泛型参数:

1.    Params:执行Async时需要传入的参数,可用于在后台任务中使用
2.    Progress:界面显示当前进度,指定该泛型为进度单位
3.    Result:任务执行完毕后的返回值类型

还需要重写AsyncTest中的几个方法完成对任务的定制:

1.    onPreExecute()
后台任务开始执行之前调用,用于进行一些界面上的初始化操作
2.    doInBackground()
这里处理所有的耗时任务,如果需要更新UI元素,可以调用publishProgress()方法来完成
3.    onProgressUpdate()
当在后台任务中调用publishProgress()后,onProgressUpdate()会很快被调用。这个方法可以进行UI操作
4.    onPostExecute()
当后台任务执行完毕并通过return语句返回时,这个方法会很快被调用。返回的数据作为参数传递到系方法中,可以利用返回的数据进行一些UI操作 

启动任务:

new xxx().execute();

三、服务的基本用法

1.定义一个服务

创建一个xx类继承Service类,重写Service类的一些方法:

onCreate()方法会在服务创建的时候调用
onStartCommand()方法会在每次服务启动的时候调用,如果希望服务一启动就立刻执行某个动作,可以将逻辑写在onStartCommand方法里
onDestroy()方法会在服务销毁的时候调用
 

在AndroidManifest.xml中注册服务:

public class MyService extends Service {
    public MyService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d("TAG","服务创建好了");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d("TAG","服务启动了");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d("TAG","服务销毁了");
    }
}

一句话,创建服务类MyService继承Service(),并在AndroidManifest.xml中注册,这样一个服务就定义好了

Tips:

在MyService的任何一个位置调用stopSelf()方法就能让这个服务停止下来

2.启动和停止服务

修改activity_main.xml代码:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/start_service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Start Service"/>

    <Button
        android:id="@+id/stop_service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Stop Service"/>

</LinearLayout>

修改MianActivity代码:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button startServiceBtn = findViewById(R.id.start_service);
        Button stopServiceBtn = findViewById(R.id.stop_service);
        startServiceBtn.setOnClickListener(this);
        stopServiceBtn.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.start_service:
                Intent startIntent = new Intent(this, MyService.class);
                //启动服务
                startService(startIntent);
                break;
            case R.id.stop_service:
                Intent stopIntent = new Intent(this, MyService.class);
                //停止服务
                stopService(stopIntent);
                break;
        }
    }
}

3.活动和服务进行通信

public class MyService extends Service {
    public MyService() {
    }

    private DownloadBinder mBinder = new DownloadBinder();

    class DownloadBinder extends Binder{
        public void startDownload(){
            Log.d("MyService","开始下载");
        }

        public int getProgress(){
            Log.d("MyService","获取下载进度");
            return 0;
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d("MyService","服务创建");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d("MyService","服务执行");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d("MyService","服务销毁");
    }
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/start_service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Start Service"/>

    <Button
        android:id="@+id/stop_service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Stop Service"/>

    <Button
        android:id="@+id/bind_service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Bind Service"/>

    <Button
        android:id="@+id/unbind_sewrvice"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Unbind Service"/>

</LinearLayout>
public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private MyService.DownloadBinder downloadBinder;

    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
             downloadBinder= (MyService.DownloadBinder) service;
             downloadBinder.startDownload();
             downloadBinder.getProgress();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button startService = findViewById(R.id.start_service);
        Button stopService = findViewById(R.id.stop_service);
        Button bindService = findViewById(R.id.bind_service);
        Button unbindService = findViewById(R.id.unbind_sewrvice);
        startService.setOnClickListener(this);
        stopService.setOnClickListener(this);
        bindService.setOnClickListener(this);
        unbindService.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.start_service:
                Intent startIntent = new Intent(this, MyService.class);
                startService(startIntent);
                break;
            case R.id.stop_service:
                Intent stopIntent = new Intent(this, MyService.class);
                stopService(stopIntent);
                break;
            case R.id.bind_service:
                Intent bindIntent = new Intent(this, MyService.class);
                //绑定活动和服务,第一个参数是Intent对象,第二个参数是ServiceConnection的实例,第三个参数表示活动和服务绑定后自动创建服务
                bindService(bindIntent,connection,BIND_AUTO_CREATE);
                break;
            case R.id.unbind_sewrvice:
                unbindService(connection);
                break;
            default:
                break;
        }
    }
}

四、服务的生命周期

调用startService()方法后,又调用stopService()方法,服务中的onDestroy()方法就会执行。

类似,调用bindService()方法后,又调用unbindService()方法,服务中的onDestroy()方法也会执行。

既调用startService(),又调用bindService(),必须同时调用stopService()和unbindService()方法,onDestroy()方法才会执行。

五、服务的更多使用技巧

1.使用前台服务

前台服务的效果类似于通知

修改MyService:

public void onCreate() {
    super.onCreate();
    Intent intent = new Intent(this, MainActivity.class);
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
    //Android O以上版本需要开启渠道才能显示通知或前台服务
    if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){
        NotificationManager notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
        NotificationChannel notificationChannel = new NotificationChannel("007", "jack", NotificationManager.IMPORTANCE_HIGH);
        notificationManager.createNotificationChannel(notificationChannel);
    }
    //Android O以上需要传递两个参数
    Notification notification = new NotificationCompat.Builder(this, "007")
            .setContentTitle("标题")
            .setContentText("内容")
            .setWhen(System.currentTimeMillis())
            .setSmallIcon(R.mipmap.ic_launcher)
            .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
            .setContentIntent(pendingIntent)
            .build();
    startForeground(1,notification);
}

2.使用IntentService

IntentService是一个异步的、会自动停止的服务(自动开启线程,执行完毕后会自动调用stopService())


完! 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值