1 介绍
Android四大组件之一,与Activity类似,也有生命周期,两者都是Context派生出来的,因此都可以调用Context里的getResource()和getContentResolver()。
2 创建一个service
比如我们创建一个名为MyService的类,继承Service基类。
public class Myservices extends Service {
String TAG = "MyService";
MyBinder myBinder;
public class MyBinder extends Binder {
public void printString() {
Log.i(TAG, " ---- access service ---- ");
}
}
//该方法需重写,返回一个Binder对象,用于访问者与service通信
@Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "onBind");
return myBinder;
}
@Override
public boolean onUnbind(Intent intent) {
Log.d(TAG, "onUnbind");
return super.onUnbind(intent);
}
@Override
public void onCreate() {
super.onCreate();
//一定要创建一个MyBinder对象,用于在onBind()被调用时返回
myBinder = new MyBinder();
Log.d(TAG, "onCreate");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy");
}
}
onBind方法必须要实现,用于service的绑定;onCreate方法在service被创建时调用;onStartCommand方法在service被启动的时候调用;onDestroy方法是在service被关闭前被调用。
3 配置AndroidManifest.xml
只需在xml文件中进行如下配置即可,添加一个service,并配置这个service的intent-filter,添加action元素,ok搞定。
<service android:name = ".MyService">
<intent-filter>
<action android:name = "com.example.myapplication.MY_SERVICE"/>
</intent-filter>
</service>
4 启动service
两种方式启动,如下
- 使用Context的startService()方法启动,使用该方法启动,访问者与service之间没有关联,即使访问者结束运行,改service仍然运行,且两者之间不能很方便的进行数据交互。
- 使用Context的bindService()方法绑定service,这时访问者与service进行了绑定,一旦访问者退出,service也会结束。此外,使用该方法还可以很方便的进行数据访问。
startService()方法使用
//创建一个Intent
final Intent intent = new Intent();
intent.setAction("com.example.myapplication.MY_SERVICE");
intent.setPackage("com.example.myapplication");
//启动service
startService(intent);
//停止service
stopService(intent);
bindService()方法使用
//创建一个Binder
Myservice.MyBinder myBinder;
//创建一个serviceContention
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
myBinder = (Myservices.MyBinder)service;
Log.i(TAG, "onServiceConnected");
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.i(TAG, "onServiceDisconnected");
}
};
//创建Intent
final Intent intent = new Intent();
intent.setAction("com.example.myapplication.MY_SERVICE");
intent.setPackage("com.example.myapplication");
//绑定service
bindService(intent,conn, Service.BIND_AUTO_CREATE);
//访问service
myBinder.printString();
//停止service
unbindService(conn);
这里用到了ServiceConnection,这是一个用于监听访问者与service之间联接情况的类。service与访问者成功联接时,回调onServiceConnected方法,该方法的参数IBinder service是service端返回的一个代理对象,该对象赋值给myBinder,这样myBinder就可以调用printString()方法了。当service与访问者之间断开联接时,回调onServiceDisconnected方法。
5 实例
我写了个小例子,简单说一下,这个例子可以跑通,已经经过测试。该测试app保持一贯的简约大气风格,仅仅有5个按键和一个textview。实现的功能就是通过点击按钮执行相应的动作,start是使用startService方法启动service,与之对应的按钮是stop。bind按钮是采用bindService方法来绑定service,绑定后点击acess可以访问service。
AndroidManifest.xml文件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapplication">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".MyServices">
<intent-filter>
<action android:name="MY_SERVICE"/>
</intent-filter>
</service>
</application>
</manifest>
MainActivity.java文件
package com.example.myapplication;
import androidx.appcompat.app.AppCompatActivity;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
Button start,stop,bind,unBind,acess;
TextView textshow;
MyServices.MyBinder myBinder;
public String TAG = "MainActivity";
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i(TAG, "onServiceConnected");
myBinder = (MyServices.MyBinder)service;
textshow.setText("onServiceConnected");
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.i(TAG, "onServiceDisconnected");
}
};
final Intent intent = new Intent();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textshow = findViewById(R.id.text_show);
start = findViewById(R.id.startService);
stop = findViewById(R.id.stopService);
bind = findViewById(R.id.bindService);
unBind = findViewById(R.id.unBindService);
acess = findViewById(R.id.acessService);
intent.setAction("MY_SERVICE");
intent.setPackage("com.example.myapplication");
start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startService(intent);
}
});
stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
stopService(intent);
}
});
bind.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
bindService(intent,conn,Service.BIND_AUTO_CREATE);
}
});
unBind.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
unbindService(conn);
}
});
acess.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
textshow.setText(myBinder.getString());
}
});
}
}
MyServices.java文件
package com.example.myapplication;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
public class MyServices extends Service {
public String TAG = "MyService";
MyBinder myBinder = new MyBinder();
public class MyBinder extends Binder {
public String getString() {
Log.i(TAG, " ---- access service ---- ");
return TAG;
}
}
@Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "onBind return myBinder"+myBinder);
return myBinder;
}
@Override
public boolean onUnbind(Intent intent) {
Log.i(TAG, "onUnbind");
return super.onUnbind(intent);
}
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "onCreate");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "onDestroy");
return super.onStartCommand(intent, flags, startId);
}
}
布局文件
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/text_show"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<Button
android:text="startService"
android:id="@+id/startService"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:text="stopService"
android:id="@+id/stopService"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:text="bindService"
android:id="@+id/bindService"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:text="unBindService"
android:id="@+id/unBindService"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:text="acessService"
android:id="@+id/acessService"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
网友评论