专栏首页緣來來來安卓基础干货(八):安卓进程的学习

安卓基础干货(八):安卓进程的学习

服务和进程优先级

  • 什么是服务? windows下的服务:没有界面、长期运行在后台的应用程序; android下的服务:应用程序的一个组件,没有界面activity,长期运行在后台; 进程:是应用程序运行的载体。 进程与应用程序之间的关系: linux操作系统创建一个进程,这个进程负责运行dalvik虚拟机,Android的应用程序都是运行在dalvik虚拟机上的。
  • 进程的生命周期: 1、应用程序一启动的时候就创建了进程; 2、当应用程序退出的时候进程并没有退出; 3、只有手工停止这个进程,进程才会结束; 操作系统尽量长时间的运行应用程序的进程,为了保证内从空间不被大量占用,它会按照进程的优先级,从低到高一级一级的杀死进程,直到内存空间被清理的差不多。

进程的等级:

  1. Foreground process(前台进程) 应用程序,用户正在操作,activity的onresume方法被执行了,可以相应点击事件。
  2. Visible process (可视进程) 应用程序的ui界面,用户还可以看到,但是不能操作了。
  3. Service process (服务进程) 应用程序没有界面,但是有一个后台的服务还处于运行状态
  4. Background process(后台进程) 应用程序没有服务处于运行状态,应用程序被最小化了,activity执行了onstop方法
  5. Empty process(空进程) 没有任何组件运行,所有的activity都关闭了,任务栈清空了

服务的特点

  • 服务的特点: 服务被创建时调用onCreate、onStartCommand; 服务只能被创建一次,可以开启多次onStartCommand; 服务只能被停止一次; 没有onPause、onStop、onResume、onRestart方法,因为service没有界面,长期运行在后台。
  • 生命周期的方法: onCreate:服务被创建的时候调用这个方法; onStartCommand :开启服务 onDestroy:销毁服务

电话窃听器的模板代码(重点)

  • 步骤: 1、在工程中添加一个服务Service,重写onCreate方法; 2、在清单文件中配置服务; 3、在activity中开启服务; 4、在onCreate方法中使用TelephonyManager监听电话的状态; 5、在清单配置文件中添加权限
  • 示例代码:

1、在工程中添加一个服务Service,重新onCreate方法:

public class DHQTService extends Service {
    /**
    * 当服务被创建的时候调用这个方法
    */
    @Override
    public void onCreate() {
    System.out.println("=========onCreate=========");
    super.onCreate();

    TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
    tm.listen(new MyListener(), PhoneStateListener.LISTEN_CALL_STATE);

    }
}

2、在清单文件中配置服务:

<service android:name="com.itheima.dhqtq.DHQTService"></service>

3、在activity中开启服务:

service = new Intent(this,DHQTService.class);
//开启服务
startService(service);

4、在onCreate方法中使用TelephonyManager监听电话的状态:

/**
 * 当服务被创建的时候调用这个方法
 */
@Override
public void onCreate() {
    System.out.println("=========onCreate=========");
    super.onCreate();

    TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
    tm.listen(new MyListener(), PhoneStateListener.LISTEN_CALL_STATE);
}


/**
*自定义一个电话状态监听器,监听电话
*/
private class mylistener extends phonestatelistener {

    private MediaRecorder r;

    @Override
    public void onCallStateChanged(int state, String incomingNumber) {

        try {
            // super.onCallStateChanged(state, incomingNumber);
            System.out.println("====state===============" + state);
            switch (state) {
            case TelephonyManager.CALL_STATE_IDLE:// 闲置状态
                System.out.println("关闭录音机,上传音频文件..................");

                if(r != null){
                    r.stop();
                    r.release();
                    r = null;
                    //上传文件
                }
                break;

            case TelephonyManager.CALL_STATE_RINGING:// 闲置状态
                System.out.println("准备好录音机,准备录音..................");

                r = new MediaRecorder();

                r.setAudioSource(MediaRecorder.AudioSource.MIC);
                r.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);

                //r.setOutputFile("/mnt/sdcard/info.3gp");
                r.setOutputFile(Environment.getExternalStorageDirectory()+"/info.3gp");
                r.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
                r.prepare(); 

                break;

            case TelephonyManager.CALL_STATE_OFFHOOK:// 闲置状态
                System.out.println("开始录音..................");
                r.start();
                break;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

5、在清单配置文件中添加权限:

<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

start开启服务的生命周期(重点)

  • 服务的特点: 服务被创建时调用onCreate、onStartCommand; 服务只能被创建一次,可以开启多次onStartCommand; 服务只能被停止一次; 没有onPause、onStop、onResume、onRestart方法,因为service没有界面,长期运行在后台。
  • 生命周期的方法:
onCreate:服务被创建的时候调用这个方法;
onStartCommand :开启服务
onDestroy:销毁服务

bind方式开启服务的生命周期(重点)

bindService绑定服务、unBindService解除绑定的服务;
服务是在被绑定的时候被创建,调用oncreate、onbind方法;
服务只能被绑定一次;
服务只能被解除一次,接触绑定的时候调用onUnbind、onDestrory方法,如果多次解除绑定会抛出异常;

推荐的方式:

startService:开启并创建一个服务,服务长期运行在后台;
bindService:绑定服务,可以调用服务里面的方法;
unBindService:解除服务,停止服务里面的方法;
stopService:停止服务,销毁服务对象;

为什么要引入bindservice的API

为了调用服务中的业务逻辑方法。

绑定服务调用服务方法的过程

通过bindservice方式实现调用服务里面业务逻辑方法:

步骤:

1、在服务类中创建一个中间人MyBinder,继承了Binder,Binder实现了IBinder接口:
    public class MyBinder extends Binder{
    }

2、在服务类里面创建了一个MyBinder的成员变量:
    private MyBinder myBinder;

3、在MyBinder类中写一个方法用于调用服务的业务逻辑方法:
    public class MyBinder extends Binder{

        //使用中间人调用服务里的方法
        public void callMethodInService(){
            methodInService();
        }

    }

4、在activity中bindService时,定义了ServiceConnection,在这个连接中实现了两个:

    private class MyConn implements ServiceConnection {
        /**
         * 服务连接成功时调用这个方法
         */
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //得到服务绑定成功后返回的中间人MyBinder对象
            myBinder = (MyBinder) service;

        }

        /**
         * 服务断开成功时调用这个方法
         */
        @Override
        public void onServiceDisconnected(ComponentName name) {
            System.out.println("-------onServiceDisconnected-------");
        }
    }

5、通过在activity中通过中间人条用服务的业务逻辑方法:
    myBinder.callMethodInService();

绑定服务抽取接口(重点)

接口(interface): 对外开放暴露的功能,但是不会暴露功能实现的细节; 让中间人实现服务接口的目的:只对外暴露接口里面业务逻辑方法,隐藏中间人里面的其他方法;

步骤:

1、创建一个服务的接口类,里面包含需要对外暴露的业务逻辑方法:
    public interface IService {
        public void callMethodInService();
    }

2、让服务中的中间人实现了服务的接口类:
    private class MyBinder extends Binder implements IService{

    //(实现服务接口中的方法)使用中间人调用服务里的方法
    public void callMethodInService(){
        methodInService();
       }
    }

3、在activity中声明接口的成员变量:
    private IService myBinder;

4、强制转换成服务的接口类型
    private class MyConn implements ServiceConnection {

    /**
     * 服务连接成功时调用这个方法
     */
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        //强制转换成服务的接口类型
        myBinder = (IService) service;
    }

 5、在activity中通过接口的成员变量调用服务的业务逻辑方法:
    public void call(View view){
    myBinder.callMethodInService();

    }

绑定服务的应用场景

应用场景:

1、需要在后台运行一定的业务逻辑,而且需要与服务器端交互数据,都是写在服务里面的。

2、天气预报、股票行情软件;

利用服务注册广播接收者

操作频繁的广播事件,如果只是在清单配置文件配置,是不生效的。需要使用代码注册才能生效;

步骤:

// 注册广播接收者
// 1、得到广播接收者的对象
ScreenBroadCastReceiver screenReceiver = new ScreenBroadCastReceiver();

// 2、创建一个intentFilter对象
IntentFilter filter = new IntentFilter();

// 3、注册接收的事件类型
filter.addAction("android.intent.action.SCREEN_ON");
filter.addAction("android.intent.action.SCREEN_OFF");

// 4、注册广播接收者
this.registerReceiver(screenReceiver, filter);

远程服务aidl的写法(重点)

本地服务:写在自己的应用程序的工程里的服务 ,使用自己应用程序的进程运行这个服务;

远程服务:写在别的应用程序的工程里的服务,使用别的应用程序的进程运行这个服务(安装在同一个手机上的应用程序);

IPC: Inter Process Communication(进程间的通讯);

aidl: Android Interface definition language 安卓接口定义语言;

aidl的接口类里面不需要public 、protected、private 等修饰符,默认是公开共享;

步骤:
1、创建一个服务的接口类,里面包含需要对外暴露的业务逻辑方法: 
2、让服务中的中间人实现了服务的接口类:
3、修改并拷贝接口文件:
4、在本地服务的工程中的activity里,绑定服务:
5、通过接口调用远程服务的方法:

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Flutter开发环境搭建

    对于上文Android Studio✗部分,只需要在AndroidStudio中的Plugin中安装Flutter插件即可。 对于'Some android l...

    吴延宝
  • NDK r17b 怎么运行mk老项目

    虽然我也很想使用 cmake 去创建 ndk 项目,奈何 Android 官方文档和我买的开发书上对于 cmake 都显得资料过少,对于新手来说不利于快速学习整...

    爱因斯坦福
  • 番外篇-Flutter初识三问

    在Android中,您可以通过直接对view进行改变来更新视图。然而,在Flutter中Widget是不可变的,不会直接更新,而必须使用Widget的状态。

    吴延宝
  • docker学习系列4 简单总结 docker-curriculum

    来源:https://docker-curriculum.com/ 这篇文章不错,可以作为第一篇 docker 的入门,我简单总结了下。顺便重温下之前的内容。...

    mafeifan
  • 说下browserslist

    browserslist 是一个开源项目 见到有些package.json里会有如下的配置参数

    mafeifan
  • 是时候学习Flutter了

    Flutter是谷歌在2018年2月份的谷歌IO大会上推出的一款跨平台的UI框架,可以快速的在Android和IOS平台上构建高质量的原生用户界面。可以与你现有...

    吴延宝
  • 如何快速了解一款产品(二)

    不是所有的产品用户都会在微博、贴吧、知乎等社区类平台反馈吐槽的,这个要根据自己的产品类型和用户类型去获取。

    靠谱先生
  • 如何优雅的从网络加载点九图?

    其实点九图和我们用的其他格式的图没有什么大的不同,只不过是在图片的四周各增加了1px的纯黑(#FF000000)的线进行标记。例如:

    吴延宝
  • 能动手就别吵吵!

    自从上回跑通了Hello World后,鲍勃对Flutter的信心大增啊。心里琢磨着能不能用Flutter实现公司现在正在做的APP的效果呢!说做就做,马上拿起...

    吴延宝
  • Android轻应用开发神器!

    推荐一款开源的轻应用开发框架RapidView:[https://github.com/Tencent/RapidView)

    吴延宝

扫码关注云+社区

领取腾讯云代金券