标签:
service用于长期在后台处理任务,而不需要对用户可见。也可以使用IntentService,它是service子类,在处理后台任务时,不需要你自己开线程,可以直接在 onHandleIntent()中进行任务。
<span style="font-size:14px;">1.<manifest ... >
...
<application ... >
<service android:name=".ExampleService"
android:exported="false"
/>
...
</application>
</manifest>
public class HelloIntentService extends IntentService {
A constructor is required, and must call the super IntentService(String)
constructor with a name for the worker thread.
public HelloIntentService() {
super("HelloIntentService");
}
* The IntentService calls this method from the default worker thread with
* the intent that started the service. When this method returns, IntentService
* stops the service, as appropriate.
@Override
protected void onHandleIntent(Intent intent) {
// Normally we would do some work here, like download a file.
// For our sample, we just sleep for 5 seconds.
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// Restore interrupt status.
Thread.currentThread().interrupt();
}
}
}</span><span style="font-size:14px;"> </span>
使用intentservice,在任务结束后会自动关闭服务。
b.使用Messenger,适用于需要跨进程通讯且线程安全且非并发,同一个时间只能接受到一个请求,你可以使用Messenger和Handler这2个 类来进行service和client的交互。
服务端建立信使对象,通过通过onbind将服务端信使对象放在IBind中回调给客户端,这样子客户端就可以拿到服务端信使对象,使用服务端信使对象给服务端发信息了。
在客户端连接上服务端后,可以建立客户端信使对象,将客户端信使对象以消息的形式,发送给服务端,服务端拿到客户端信使对象后可以给客户端发消息。
这个是线程安全的。因为都是在同一个队列里,在同一个线程里进行的。它本身是基于AIDL构建的。
c.使用AIDL,适用于需要跨进程,且非线程安全,能够同一时间处理多个请求的场合。
它的使用是创建一个.aidl file文件,里面定义接口,然后android sdk tool使用它来生成一个抽象类,抽象类里实现各种接口方法。
注意:对于大多数应用,我们都不应该使用AIDL来bindservice.因为这会使得结果更复杂。
<span style="font-size:14px;">public class LocalService extends Service {
// Binder given to clients
private final IBinder mBinder = new LocalBinder();
// Random number generator
private final Random mGenerator = new Random();
//Class used for the client Binder. Because we know this service always
//runs in the same process as its clients, we don't need to deal with IPC.
public class LocalBinder extends Binder {
LocalService getService() {
// Return this instance of LocalService so clients can call public methods
return LocalService.this;
}
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
//method for clients
public int getRandomNumber() {
return mGenerator.nextInt(100);
}
}</span><span style="font-size:14px;">public class BindingActivity extends Activity {
LocalService mService;
boolean mBound = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
protected void onStart() {
super.onStart();
// Bind to LocalService
Intent intent = new Intent(this, LocalService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
@Override
protected void onStop() {
super.onStop();
// Unbind from the service
if (mBound) {
unbindService(mConnection);
mBound = false;
}
}
//** Called when a button is clicked (the button in the layout file attaches to
// * this method with the android:onClick attribute)
public void onButtonClick(View v) {
if (mBound) {
// Call a method from the LocalService.
// However, if this call were something that might hang, then this request should
// occur in a separate thread to avoid slowing down the activity performance.
int num = mService.getRandomNumber();
Toast.makeText(this, "number: " + num, Toast.LENGTH_SHORT).show();
}
}
// Defines callbacks for service binding, passed to bindService()
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className,
IBinder service) {
// We've bound to LocalService, cast the IBinder and get LocalService instance
LocalBinder binder = (LocalBinder) service;
mService = binder.getService();
mBound = true;
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
mBound = false;
}
};
}</span>
如果您只需要在 Activity 可见时与服务交互,则应在 onStart() 期间绑定,在 onStop() 期间取消绑定。
如果您希望 Activity 在后台停止运行状态下仍可接收响应,则可在 onCreate() 期间绑定,在 onDestroy() 期间取消绑定。请注意,这意味着您的 Activity 在其整个运行过程中(甚至包括后台运行期间)都需要使用服务,因此如果服务位于其他进程内,那么当您提高该进程的权重时,系统终止该进程的可能性会增加
下面是个完整的例子;客户端和服务端使用Messenger来通讯。
服务端:Server_Service
<span style="font-size:14px;">package com.example.administrator.service_messenger;
import android.app.Service;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.widget.Toast;
/**
* 在manifest清单文件中声明service为另起新的进程。
*/
public class Server_Service extends Service {
private Messenger clientMessenger;
/**
* 服务端的handler
*/
class ServerHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case Client.MSG_FROM_CLIENT:
String fromClient = msg.getData().getString("msgFromClient");
//收到来自客户端的信息
Toast.makeText(getApplicationContext(), fromClient, Toast.LENGTH_SHORT).show();
//回复一下客户端
Message msgFromServer = Message.obtain(null, Client.MSG_FROM_SERVER);
msgFromServer.arg1 =200;
try {
clientMessenger.send(msgFromServer);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
case Client.MSG_FROM_CLIENT_MESSE: //得到客户端的信使对象
clientMessenger = msg.replyTo;
break;
}
}
}
/**
* 服务端的Messenger,使用服务端的handler做参数构造。
*/
final Messenger serverMessenger = new Messenger(new ServerHandler());
/**
* 我们在这里使用服务端的信使对象serverMessenger的IBinder,将其返回给客户端中的
* serviceConntected
*/
@Override
public IBinder onBind(Intent intent) {
Toast.makeText(getApplicationContext(), "客户端绑定服务端成功", Toast.LENGTH_SHORT).show();
return serverMessenger.getBinder();
}
@Override
public void unbindService(ServiceConnection conn) {
super.unbindService(conn);
Toast.makeText(getApplicationContext(), "客户端取消了服务绑定", Toast.LENGTH_SHORT).show();
}
}
</span>在manifest下配置:
<span style="font-size:14px;"><service android:name=".Server_Service"
android:process=":v1"/></span><span style="font-size:14px;">package com.example.administrator.service_messenger;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Toast;
import java.io.UnsupportedEncodingException;
import java.util.Calendar;
public class Client extends AppCompatActivity {
public static final int MSG_FROM_CLIENT = 1;
public static final int MSG_FROM_CLIENT_MESSE = 2;
public static final int MSG_FROM_SERVER = 3;
//在客户端里拿到了服务端的信使对象
Messenger serverMessenger = null;
//标记是否已经连上了服务端
boolean mBound;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_client);
//绑定服务
findViewById(R.id.bt_bind).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
bindService();
}
});
//通过服务端的信使来发信息给服务端
findViewById(R.id.bt_send).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
sendInfoToServer();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
});
//手动解绑服务
findViewById(R.id.bt_unbind).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
unBindService();
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
//在activity销毁时,可以选择取消绑定服务
unBindService();
}
//客户端的handler
private Handler clientHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_FROM_SERVER:
Toast.makeText(getApplicationContext(), "server received :"+msg.arg1+"", Toast.LENGTH_SHORT).show();
break;
}
}
};
/**
* 客户端的Messenger,使用客户的handler做参数构造。
*/
final Messenger clientMessenger = new Messenger(clientHandler);
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
//当我们连接上服务端后,会调用该方法。在方法里会回调给我们IBinder对象,
//由于bindservice绑定服务后,服务端返回给客户端的IBinder是同一个。
//所以这里我们可以利用IBinder来构建服务端里的信使对象。
//之后有了服务端的信使对象,就可以随便网服务端发送信息了。
//构建服务端信使对象
serverMessenger = new Messenger(service);
mBound = true;
//并将客户端的messenger发给服务端,让服务端也可以给客户端发送消息
Message msg = Message.obtain(null, MSG_FROM_CLIENT_MESSE);
msg.replyTo = clientMessenger;
try {
serverMessenger.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
public void onServiceDisconnected(ComponentName className) {
// 当连接服务端异常时调用
serverMessenger = null;
mBound = false;
}
};
private void sendInfoToServer() throws UnsupportedEncodingException {
if (!mBound) return;
Message msg = Message.obtain(null, MSG_FROM_CLIENT, 0, 0);
String strMsg = "server received:" + Calendar.getInstance().getTime();
Bundle data = new Bundle();
data.putString("msgFromClient", strMsg);
msg.setData(data);
try {
serverMessenger.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
protected void onStart() {
super.onStart();
// 在界面可见时,可以选择去绑定服务
}
@Override
protected void onStop() {
super.onStop();
// 在界面不可见时,可以选择去解绑服务
}
private void bindService() {
bindService(new Intent(this, Server_Service.class), mConnection,
Context.BIND_AUTO_CREATE);
}
private void unBindService() {
if (mBound) {
unbindService(mConnection);
mBound = false;
}
}
}
</span>
标签:
原文地址:http://blog.csdn.net/baidu_26994091/article/details/51780052