android四大组件之Service

本文详细介绍了Android中的Service组件,包括创建、启动、绑定本地及远程服务的过程,并解释了如何使用AIDL技术实现跨进程调用。
Service是一种在后台运行,没有界面的组件,由其他组件调用开始。
创建Service,定义类继承Service,AndroidManifest.xml中定义<service>

创建service类
public class MyService extends Service {


@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return new MyBinder();
}


@Override
public void onCreate() {

System.out.println("onCreate");
}


@Override
public void onStart(Intent intent, int startId) {
System.out.println("onStart");

}


@Override
public void onDestroy() {

System.out.println("onDestroy");
}


}
清单文件中注册
<service android:name=".ServerService">
            <intent-filter >
                <action android:name="com.li.server"/>
            </intent-filter>
     </service>

开启Service,在其他组件中调用startService方法
Intent intent=new Intent("com.li.server");
startService(intent);

停止Service,调用stopService方法
stopService(intent);


11.3. 绑定本地服务
使用bindService绑定服务,传入一个自定义的ServiceConnection用来接收IBinder
private class MyConn implements ServiceConnection
{


@Override
public void onServiceConnected(ComponentName name, IBinder service) {

invoke=(InvokeMethod) service;
}


@Override
public void onServiceDisconnected(ComponentName name) {


}

}

定义一个业务接口,其中定义需要的使用的方法
public interface InvokeMethod {


public void helloWorld();

}
服务中自定义一个IBinder继承Binder并实现业务接口,在onBind方法中返回

class MyBind extends Binder implements InvokeMethod
{


@Override
public void helloWorld() {
MyService.this.helloWorld();

}

}


IBinder binder=new MyBind();
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return binder;
}
调用端将IBinder转为接口类型,调用接口中的方法即可调用到服务中的方法


invoke=(InvokeMethod) service;
invoke.helloworld();


绑定远程服务
远程绑定服务时无法通过同一个接口来调用方法,这时就需要使用AIDL技术
将接口扩展名改为“.aidl”
去掉权限修饰符
gen文件夹下会生成同名接口
将服务中自定义的IBinder类改为继承接口中的Stub
ServiceConnection中返回的IBinder是代理对象,不能使用强转,改用Stub.asInterface()



代码如下:
服务端:
public class ServerService extends Service {


@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return new MyBinder();
}


@Override
public void onCreate() {

System.out.println("onCreate");
}


@Override
public void onStart(Intent intent, int startId) {
System.out.println("onStart");

}


@Override
public void onDestroy() {

System.out.println("onDestroy");
}
    class MyBinder extends Stub
    {


@Override
public void helloworld() throws RemoteException {

ServerService.this.helloworld();

}
   
    }
public void helloworld() {
System.out.println("你好  世界");

}



}
客户端:
public class MainActivity extends Activity {


Intent intent=new Intent("com.li.server");
private ServiceConnection conn=new MyConn();
InvokeInterface invoke;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }


    
    public void start(View v)
    {
    startService(intent);
    }
    public void stop(View v)
    {
    stopService(intent);
    }
    public void bind(View v)
    {
    bindService(intent, conn, 1);
   
    }
    public void unbind(View v)
    {
    unbindService(conn);
    }
    public void invoke(View v)
    {
    try {
invoke.helloworld();
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
    }
    
    
    class MyConn implements ServiceConnection
    {


@Override
public void onServiceConnected(ComponentName name, IBinder service) {

invoke=Stub.asInterface(service);
}


@Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub

}
   
    }
    


}




AIDL使用自定义类型
AIDL默认只能使用Java中基本数据类型和String、List、Map,List和Map中的元素类型也只能是这些类型。
如果需要使用其他类型数据,使用的类必须实现Parcelable接口以完成序列化和反序列化工作
重写 public void writeToParcel(Parcel dest, int flags)
定义 public static final Parcelable.Creator<Person> CREATOR
定义该类对应的AIDL
package 包名
parcelable 类名
在接口AIDL中导入该类,注意:即使是同一个包也需要导入



### Service 的作用 ServiceAndroid 四大组件之一,其主要作用是在后台执行长时间运行的任务,而不需要与用户进行交互。它没有界面,适用于执行如网络请求、播放音乐、文件 I/O 等需要在后台持续运行的操作。Service 可以独立于 Activity 运行,即使用户切换到其他应用,Service 仍然可以在后台继续运行 [^1]。 此外,Service 也可以被其他应用调用,从而提供一些特定的功能,例如后台数据处理或资源共享 [^2]。 ### Service 的生命周期 Service 的生命周期相对简单,主要包含以下几个关键方法: - `onCreate()`:当 Service 第一次被创建时调用,用于执行一次性初始化操作。 - `onStartCommand(Intent intent, int flags, int startId)`:当通过 `startService()` 启动 Service 时调用,用于处理传入的 Intent 请求。 - `onBind(Intent intent)`:当通过 `bindService()` 绑定 Service 时调用,返回一个 `IBinder` 对象用于实现组件间的通信。 - `onUnbind(Intent intent)`:当解除绑定时调用。 - `onDestroy()`:当 Service 被销毁时调用,用于释放资源。 根据启动方式的不同,Service 的生命周期会有所不同。 ### Service 的启动方式 Service 可以通过两种方式启动: 1. **通过 `startService()` 启动** - 使用 `startService()` 启动的 Service 会独立运行,与启动它的组件没有直接的绑定关系。 - 一旦启动,Service 会一直运行直到调用 `stopSelf()` 或外部调用 `stopService()`。 - 适用于执行一次性任务,例如下载文件或播放音乐。 2. **通过 `bindService()` 启动** - 使用 `bindService()` 启动的 Service 会与调用者(例如 Activity)建立绑定关系。 - 通过 `onBind()` 方法返回的 `IBinder` 对象,调用者可以与 Service 进行交互。 - 当调用者解除绑定时,Service 不会立即停止,只有当所有绑定都解除后,才会调用 `onUnbind()` 并最终调用 `onDestroy()` [^4]。 ### Service 的使用示例 #### 启动 Service ```java Intent serviceIntent = new Intent(context, MyService.class); context.startService(serviceIntent); ``` #### 停止 Service ```java Intent serviceIntent = new Intent(context, MyService.class); context.stopService(serviceIntent); ``` #### 绑定 Service ```java Intent serviceIntent = new Intent(context, MyService.class); context.bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE); ``` 其中,`serviceConnection` 是一个实现了 `ServiceConnection` 接口的对象,用于接收 Service 绑定后的回调。 #### 解除绑定 ```java context.unbindService(serviceConnection); ``` ### Service 的声明 每个 Service 都需要在 `AndroidManifest.xml` 文件中进行声明,否则无法正常运行。声明方式如下: ```xml <service android:name=".MyService" /> ``` ### 前台 Service 如果需要让 Service 在前台运行,以避免被系统优先级机制杀死,可以使用 `startForegroundService()` 方法启动 Service,并在 Service 中调用 `startForeground()` 方法,将 Service 提升为前台服务 [^3]。 ```java Intent serviceIntent = new Intent(context, MyForegroundService.class); context.startForegroundService(serviceIntent); ``` 在 Service 的 `onStartCommand()` 方法中: ```java Notification notification = new Notification.Builder(this, "channel_id") .setContentTitle("Foreground Service") .setSmallIcon(R.drawable.ic_notification) .build(); startForeground(1, notification); ``` ### 注意事项 - **资源管理**:由于 Service 在后台运行,需要注意资源的合理使用,避免过度消耗系统资源。 - **生命周期管理**:使用 `bindService()` 启动的 Service 必须通过 `unbindService()` 解除绑定,否则可能导致内存泄漏。 - **权限声明**:某些特殊用途的 Service(例如前台服务)可能需要在清单文件中声明额外的权限。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值