安卓基础总结 Service相关

1.服务入门

进程的等级

  1. Foreground process(前台进程)

    应用程序,用户正在操作,activity的onresume方法被执行了,可以相应点击事件。
    
  2. Visible process (可视进程)

    应用程序的ui界面,用户还可以看到,但是不能操作了。
    
  3. Service process (服务进程)

    应用程序没有界面,但是有一个后台的服务还处于运行状态
    
  4. Background process(后台进程)

    应用程序没有服务处于运行状态,应用程序被最小化了,activity执行了onstop方法
    
  5. Empty process (空进程)

    没有任何组件运行,所有的activity都关闭了,任务栈清空了
    

进程与应用程序之间的关系: linux操作系统创建一个进程,这个进程负责运行dalvik虚拟机,Android的应用程序都是运行在dalvik虚拟机上的。

  • 进程的生命周期

    1、应用程序一启动的时候就创建了进程;
    2、当应用程序退出的时候进程并没有退出;    缓存,加快下次启动的速度
    3、只有手工停止这个进程,进程才会结束;
    
    
    操作系统尽量长时间的运行应用程序的进程,为了保证内从空间不被大量占用,它会按照进程的优先级,从低到高一级一级的杀死进程,直到内存空间被清理的差不多。
    

服务的特点

  • 服务的特点:

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

    onCreate:服务被创建的时候调用这个方法;
    onStartCommand :开启服务
    onDestroy:销毁服务
    

一个简单的示例

1.启动一个service

//使用意图启动Service
Intent intent = new Intent(MainActivity.this, MyService.class);
startService(intent);

2.创建一个类继承Service

public class MyService extends Service {

@Override
public IBinder onBind(Intent intent) {

    return null;
}

//创建服务的时候调用
@Override
public void onCreate() {
    System.out.println("*****onCreate******");
    super.onCreate();
}

//启动server    每次start都会调用一次
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    System.out.println("*****onStartCommand******");
    return super.onStartCommand(intent, flags, startId);
}

//手动停止程序后会终止服务,会调用onDestroy()方法
@Override
public void onDestroy() {
    System.out.println("*****onDestroy******");
    super.onDestroy();
}
}

3.添清单文件中添加一个service

<service android:name="com.example.servicedemo.MyService"></service>

2.服务的两种开启方式

API

方式1
直接启停
startService(intent);
stopService(intent);
方式2
绑定服务的方式
bindService(intent, conn, BIND_AUTO_CREATE);
unbindService(conn);

例程

在一个程序里如果配置了某个服务,那么不管如何new,始终只有那一个服务。

public void click1(View v)
{
    //click1和click2   每次创建service都是一个东西    说明一个服务开启了就只存在一份
    Intent intent = new Intent(MainActivity.this, ServerDemo.class);
    startService(intent);
}

public void click2(View v)
{
    //click1和click2   每次创建service都是一个东西    说明一个服务开启了就只存在一份
    Intent intent = new Intent(MainActivity.this, ServerDemo.class);
    stopService(intent);
}

public void click3(View v)
{
    Intent intent = new Intent(MainActivity.this, ServerDemo.class);
    conn = new MyServiceConnection();
    bindService(intent, conn, BIND_AUTO_CREATE);
}

public void click4(View v)
{
    unbindService(conn);
}

//这里注意,使用bind的方法必须实现这个类,用于监控绑定状态
private class MyServiceConnection implements ServiceConnection 
{
    //绑定成功回调
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {   
    }
    //解除绑定回调
    @Override
    public void onServiceDisconnected(ComponentName name) {         
    }   
} 

3.使用绑定获取服务中的方法

绑定服务的应用场景

 应用场景:

 1、需要在后台运行一定的业务逻辑,而且需要与服务器端交互数据,都是写在服务里面的。
 2、天气预报、股票行情软件;

API

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


推荐的方式(启用顺序):

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

例程

注意,我们需要在后台开启一个服务,这个服务一直在运行。可以通过前台调用后台服务中的函数,从而进行应用程序和服务交互。

startService(intent);方法可以创建一个服务,如果不手动关闭(假定操作系统没有回收这个服务),适用于创建一个后台服务。

bindService(intent, new MyServiceConnection(), BIND_AUTO_CREATE);方法用于绑定一个服务。在startService方法后调用。

1.MainActivity

public class MainActivity extends Activity {

private MyBind serverRet;

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

    Intent intent = new Intent(MainActivity.this, BackgroundService.class);
    startService(intent);

    bindService(intent, new MyServiceConnection(), BIND_AUTO_CREATE);
}

public void click1(View v)
{
    //调用服务的方法
    serverRet.callPaly();
}

public void click2(View v)
{
    serverRet.callPause();
}

public void click3(View v)
{
    serverRet.callReplay();
}

class MyServiceConnection implements ServiceConnection
{

    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        //返回服务中包含要调用方法的类
        serverRet = (MyBind) service;
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
    }
}
}

Service

public class BackgroundService extends Service {

@Override
public IBinder onBind(Intent intent) {

    return new MyBind();     //返回到前台的对象,包含要执行的service中的方法
}

@Override
public void onCreate() {

    super.onCreate();
}

@Override
public void onDestroy() {

    super.onDestroy();
}


public void paly() {
    System.out.println("********paly********");
}

public void pause() {
    System.out.println("********pause********");
}

public void replay() {
    System.out.println("********replay********");
}

//继承Binder类,这是因为要返回一个实现IBinder类型接口的    实现Iservice方法,这个接口里面的函数都是我们自己定义的要传给前台的函数
public class MyBind extends Binder implements Iservice
{

    @Override
    public void callPaly() {
        paly();
    }

    @Override
    public void callPause() {
        pause();
    }

    @Override
    public void callReplay() {
        replay();
    }
}
}

Iservice 接口中定义我们要传递的方法

public interface Iservice {

    public void callPaly();
    public void callPause();
    public void callReplay();
}

4.获取其他进程的服务的方法

1.接口需要修改,将后缀名改为aidl(android interface defination language),并将包含这个接口的包名拷贝,在客户端也创建一个这个名字的包,也把这个aidl文件拷贝过去。

package com.example.ipc_server;

interface Iservice {

    void callServerFun();
}

2.服务端清单文件中配置service,由于是调用不同程序的服务,所以使用隐式意图。action的name是由我们自己指定,客户端在创建隐式intent时需要写入名字,就是这个字符串。

    <service android:name="com.example.ipc_server.MyServer">
        <intent-filter>
            <action android:name="com.example.ipc_server"/>
        </intent-filter>
    </service>

3.客户端

public class MainActivity extends Activity {

private Intent intent;

private ServiceConnection conn;

private Iservice serviceRet;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //开启意图
    intent = new Intent();
    intent.setAction("com.example.ipc_server");
    //绑定服务
    conn = new MyConn();
    bindService(intent, conn, BIND_AUTO_CREATE);
}


public void click(View v)
{
    try {
        serviceRet.callServerFun();
    } catch (RemoteException e) {
        e.printStackTrace();
    }
}

class MyConn implements ServiceConnection
{
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        System.out.println("*********启动服务**********");
        serviceRet = Iservice.Stub.asInterface(service);
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {

    }

}
}

5.使用服务注册监听器

两种注册类型的区别:
静态注册是当程序关闭后,如果有广播发过来,还能启动程序
动态注册的生命周期跟程序的生命周期是一样的,程序关闭后动态注册的广播是不能在接收到广播的


动态注册的优点:在Android的广播机制中,动态注册的优先级高于静态注册的优先级,因此在必要情况下,我们需要动态注册广播接收器。
静态注册的有点:动态注册广播接收器还有一个优点就是当用来注册广播的Activity关闭后,广播也就失效了,同时反映了静态注册广播的一个优势,就是无需担心广播接收器是否关闭,只要设备处于开启状态,广播接收器就能接收。

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

 步骤:

 // 注册广播接收者
    // 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);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值