zoukankan      html  css  js  c++  java
  • 安卓开发 探究服务

    前言:

      关于安卓开发的笔记,其实基本都是我复现一行代码中的代码,并加上我自己的理解并解说的,也就是自己记录着玩玩的,有问题欢迎评论区指正。

    0x01 简介

    服务service是安卓里面的四大组件之一,它的作用就是可以在应用程序关闭时,还可以继续运行,比如我们平常电脑或手机听歌的时候,我们会先打开

    音乐软件,播放音乐后,切换别的应用,干活去了对吧,但是我们在切换应用的时候,按道理应用这时候是已经挂在后台了,但是音乐还是在正常播放的

    也就是服务是支持应用程序在后台正常运行的手段。

    0x02 安卓多线程编程

    至于为什么先写多线程,一个是书上是这顺序,还有一个原因就是在于服务的干事的地方,基本都在子线程里面干的,而服务并不是自己创建子进程的,

    这需要我们在服务内部代码中去实现的,管他呢,都得学2333

    安卓多线程和java的多线程差不多的,也都是三种方式

    1.继承Thread类,重写run方法,然后创建对应的线程对象,调用start()方法,启动线程

     class OneThread extends Thread{
            public void run()
            {
                Log.d("YenKoc", "重写");
            }
        }
    OneThread one=new OneThread();
    one.start();

    2.实现Runnable接口,重写run方法,创建对应的实例,然后再新建一个Thread对象,将上面的实例传入Thread的构造方法中去,再调用start()

     class OneThread implements Runnable{
            public void run()
            {
    
            }
        }
        OneThread one =new OneThread();
        new Thread(one).start();

    3.匿名类创建子线程的方式

    new Thread(new Runnable(){
            public void run()
            {
    
            }
        }).start()

    这种是是最简单省事的,也是用的多的

    然后在子线程中是无法更新UI的,这里书里也提供了一个简单的案例,我就不提出来了,就是新建一个布局,然后设置一个按钮,一点就新建子线程去改变文本框的内容

    由于子线程中无法更新ui,也就是会出现程序崩溃的情况,这里就提出另一种完美解决安卓子进程更新ui的操作,安卓提供了一套消息处理机制,其实之前在app启动的源码中

    也看到了消息机制looper等,通过发信号的模式去启动的,这是题外话,这块我也好久没看了,又忘了233

    这里通过实例来看

    package com.example.servicetest;
    
    import androidx.appcompat.app.AppCompatActivity;
    
    import android.content.ComponentName;
    import android.content.Intent;
    import android.content.ServiceConnection;
    import android.net.IpSecManager;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.IBinder;
    import android.os.Message;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button;
    import android.widget.TextView;
    
    import java.nio.BufferUnderflowException;
    
    public class MainActivity extends AppCompatActivity implements View.OnClickListener{
        private TextView text;
        public static final int UPDATE_TEXT=1;
        private Handler handler=new Handler(){
            public void handleMessage(Message msg){
                switch (msg.what)
                {
                    case UPDATE_TEXT:
                        text.setText("Nice to meet you");
                        break;
                    default:
                        break;
                }
            }
        }
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            Button changeText=(Button)findViewById(R.id.change_text);
            changeText.setOnClickListener(this);
    
        }
        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=1;
                            handler.sendMessage(message);
                        }
                    }).start();
                default:
                    
                            
            }
    
    
        }
    }

    新建一个handler对象,并重写了handlerMessage方法,里面主要是根据消息中的what字段来选择不同的处理方式,

    然后在点击按钮后,实际上是通过创建子进程,然后在子进程中,发送了一个消息给主线程handler,然后由主线

    程来更新ui,这种异步消息处理机制,太酷了233,想当于领导在子线程里面指挥,小弟在主线程里面干活。

    至于原理也挺简单当,看图

     message:字面意思,作为通讯用的

    handler: 用来处理消息的,要重写handleMessage方法

    MessageQueue:消息队列,因为消息有先后顺序的,相当于消息容器,把消息都装到里面

    looper:消息队列的管家,一旦运行会轮询消息队列,看看里面是否有消息,如果有就发送,没有的话就阻塞

    之前使用的runOnUiThread其实就是上面那套的封装,所以很香,所以那里面是可以对ui操作的

    0x02 服务

    终于到服务了。。

    package com.example.servicetest;
    
            import android.app.Service;
            import android.content.Intent;
            import android.os.IBinder;
    
    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");
        }
        //服务创建的时候调用
        public void onCreate()
        {
            super.onCreate();
        }
        //服务每次启动时被调用
        public int onStartCommand(Intent intent,int flags,int startId)
        {
            return super.onStartCommand(intent,flags,startId);
        }
        public void onDestroy()
        {
            super.onDestroy();
        }
    
    }

    新建一个service类,然后重写onCreate()方法,onStartCommand()方法(主要逻辑是写到这里),onDestroy()方法,

    2.服务的启动和停止,组件之间的启动都是通过intent对象来启动的

    package com.example.servicetest;
    
    import androidx.appcompat.app.AppCompatActivity;
    
    import android.content.ComponentName;
    import android.content.Intent;
    import android.content.ServiceConnection;
    import android.net.IpSecManager;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.IBinder;
    import android.os.Message;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button;
    import android.widget.ProgressBar;
    import android.widget.TextView;
    
    import java.nio.BufferUnderflowException;
    
    public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
          Button startService=(Button)findViewById(R.id.start_service);
            Button stopService=(Button)findViewById(R.id.stop_service);
            startService.setOnClickListener(this);
            stopService.setOnClickListener(this);
        }
        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;
            }
        }
    
    }

    然后在MyService类改下代码

    package com.example.servicetest;
    
            import android.app.Service;
            import android.content.Intent;
            import android.os.IBinder;
            import android.util.Log;
    
    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");
        }
        //服务创建的时候调用
        public void onCreate()
        {
            super.onCreate();
            Log.d("MyService", "onCreate executed");
        }
        //服务每次启动时被调用
        public int onStartCommand(Intent intent,int flags,int startId)
        {
            Log.d("MyService", "onStartCommand: executed");
            return super.onStartCommand(intent,flags,startId);
        }
        public void onDestroy()
        {
            super.onDestroy();
            Log.d("MyService", "onDestroy: executed");
        }
    
    }

    3.活动与服务之间的通信,因为之前这种方式都是活动启动完服务之后,就不管不顾了,无法知道服务具体逻辑是什么,也控制不了,所以安卓想让活动和服务紧密一点,所以提出了Binder机制

    未完待续

  • 相关阅读:
    [kuangbin带你飞]专题十二 基础DP1 E
    hdu 1203 I NEED A OFFER! (01背包)
    hdu 2602 Bone Collector (01背包)
    hdu 4513 吉哥系列故事——完美队形II (manacher)
    hdu 2203 亲和串 (KMP)
    hdu 1686 Oulipo (KMP)
    hdu 1251 统计难题 (字典树)
    hdu 2846 Repository (字典树)
    hdu 1711 Number Sequence (KMP)
    poj 3461 Oulipo(KMP)
  • 原文地址:https://www.cnblogs.com/YenKoc/p/13874155.html
Copyright © 2011-2022 走看看