今天晚上把service的用法整理一下,service在Android中的地位仅次于activity,其重要性可见一斑。下面主要从四个部分分别讲解:
分别是startService,bindservice(两个基础用法。通过log查看生命周期)messenger和aidl(Android IPC机制主要也是通过service与binder来实现的)
编写activityInfo类来管理这四个测试的activity类,方便activity之间的跳转,简化代码
package com.example.servicetest;
public class ActivityInfo {
private String name;
private Class clazz;
public ActivityInfo(String name, Class clazz)
{
super();
this.name = name;
this.clazz = clazz;
}
public String getName()
{
return name;
}
public Class getClazz()
{
return clazz;
}
public void setName(String name)
{
this.name = name;
}
public void setClazz(Class clazz)
{
this.clazz = clazz;
}
}
测试主类 MainActivity代码:
package com.example.servicetest;
import java.util.Arrays;
import java.util.List;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
public class MainActivity extends Activity {
private ListView mListView;
private final List mData = Arrays.asList(new ActivityInfo(
"StartService", ActivityStartService.class), new ActivityInfo(
"bindService", ActivityBindService.class), new ActivityInfo(
"Menssenger", ActivityMessenger.class), new ActivityInfo("aidl",
ActivityAidl.class));
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//初始化view,个人的风格而已
initView();
}
private void initView()
{
mListView = (ListView) findViewById(R.id.lv_activity_main);
//为listview设置adapter
mListView.setAdapter(new MyAdapter(this, mData));
mListView.setOnItemClickListener(new OnItemClickListener()
{
@Override
public void onItemClick(AdapterView> arg0, View arg1, int arg2,
long arg3)
{
Intent intent = new Intent();
//通过前面设计的activityInfo得到要跳转的activity的class
intent.setClass(MainActivity.this, mData.get(arg2).getClazz());
startActivity(intent);
}
});
}
}
listView的adapter实现很简单,继承自baseAdapter,使用viewholder去优化listview,想必大家都了解。
(1)通过startService(Intent intent)的方式开启服务
package com.example.servicetest;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class ActivityStartService extends Activity implements OnClickListener {
private Button mButtonStart, mButtonStop;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.service_layout);
initView();
}
private void initView()
{
mButtonStart = (Button) findViewById(R.id.btn_start_service);
mButtonStop = (Button) findViewById(R.id.btn_stop_service);
mButtonStart.setOnClickListener(this);
mButtonStop.setOnClickListener(this);
}
@Override
public void onClick(View arg0)
{
switch (arg0.getId())
{
case R.id.btn_start_service:
//开启service
startService(new Intent(ActivityStartService.this,
StartService.class));
break;
//停止service
case R.id.btn_stop_service:
stopService(new Intent(ActivityStartService.this,
StartService.class));
break;
default:
break;
}
}
}
service的实现:
package com.example.servicetest;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
public class StartService extends Service {
private final String TAG = "StartService";
@Override
public void onCreate()
{
Log.e(TAG, "-----oncreate----");
super.onCreate();
}
@Override
public void onDestroy()
{
Log.e(TAG, "-----onDestroy----");
super.onDestroy();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Log.e(TAG, "----onStartCommand----");
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent arg0)
{
Log.e(TAG, "----onBind----");
return null;
}
@Override
public void onRebind(Intent intent)
{
Log.e(TAG, "----onReBind----");
super.onRebind(intent);
}
@Override
public boolean onUnbind(Intent intent)
{
Log.e(TAG, "----onUnbind----");
return super.onUnbind(intent);
}
}
(2)bindService的启动过程,需要注意的是通过bindService启动service时,当service正常结束的时候,是不会调用onServiceDisconnected方法的,即使手动调用了unBindService()方法。
package com.example.servicetest;
import android.app.Activity;
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.view.View.OnClickListener;
import android.widget.Button;
public class ActivityBindService extends Activity implements OnClickListener {
private Button mButtonBind, mButtonUnBind;
private final String TAG = "ActivityBindService";
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.service_layout);
initView();
}
private void initView()
{
mButtonBind = (Button) findViewById(R.id.btn_start_service);
mButtonUnBind = (Button) findViewById(R.id.btn_stop_service);
mButtonBind.setOnClickListener(this);
mButtonUnBind.setOnClickListener(this);
}
@Override
public void onClick(View arg0)
{
switch (arg0.getId())
{
case R.id.btn_start_service:
bindService(
new Intent(ActivityBindService.this, StartService.class),
mConnection, BIND_AUTO_CREATE);
break;
case R.id.btn_stop_service:
unbindService(mConnection);
break;
default:
break;
}
}
private final ServiceConnection mConnection = new ServiceConnection()
{
@Override
public void onServiceDisconnected(ComponentName arg0)
{
Log.e(TAG, "----onServiceDisconnected----");
}
@Override
public void onServiceConnected(ComponentName arg0, IBinder arg1)
{
Log.e(TAG, "----onServiceConnected----");
}
};
}
(3)messenger使用service进行IPC通信:
messenger主要是使用了Ibinder机制,其本质也是使用了aidl,但是他的好处是不用手工编写aidl文件,也不用理会aidl的生成过程。使用么三messege 和 Handler进行消息进行传递通信。因为handler是线程安全而且是一对一的通信,所以当Android IPC是一对一的时候,可以考虑使用messenger代替aidl去实现进程间通信
package com.example.servicetest;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class ActivityMessenger extends Activity implements OnClickListener {
private final String TAG = "ActivityMessenger";
private Button mButton, mButton2;
private Messenger iMessenger;
private final Handler mHandler = new Handler(new Callback()
{
@Override
public boolean handleMessage(Message arg0)
{
switch (arg0.what)
{
case RemoteService.MSG_FROM_CLIENT:
String msg = arg0.getData().getString("rsp");
Log.e(TAG, msg);
break;
default:
break;
}
return false;
}
});
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.service_layout);
initView();
}
private void initView()
{
mButton = (Button) findViewById(R.id.btn_start_service);
mButton.setOnClickListener(this);
mButton2 = (Button) findViewById(R.id.btn_stop_service);
mButton2.setOnClickListener(this);
}
@Override
public void onClick(View arg0)
{
switch (arg0.getId())
{
case R.id.btn_start_service:
bindService(
new Intent(ActivityMessenger.this, RemoteService.class),
mConnection, BIND_AUTO_CREATE);
break;
case R.id.btn_stop_service:
unbindService(mConnection);
break;
default:
break;
}
}
private final ServiceConnection mConnection = new ServiceConnection()
{
@Override
public void onServiceDisconnected(ComponentName arg0)
{
Log.e(TAG, "----onServiceDisconnected----");
}
@Override
public void onServiceConnected(ComponentName arg0, IBinder arg1)
{
Log.e(TAG, "----onServiceConnected----");
//初始化messenger
iMessenger = new Messenger(arg1);
//设置message的类型
Message message = Message.obtain(null,
RemoteService.MSG_FROM_CLIENT);
Bundle bundle = new Bundle();
bundle.putString("msg", "msg from client");
message.setData(bundle);
//这一句很重要,表明该消息的回复消息处理的handler为上面定义的mHandler。
message.replyTo = new Messenger(mHandler);
try
{
iMessenger.send(message);
} catch (RemoteException e)
{
e.printStackTrace();
}
}
};
}
下面看看RemoteService类:
package com.example.servicetest;
import android.app.Service;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
public class RemoteService extends Service {
public static final int MSG_FROM_CLIENT = 0X0001;
private final String TAG = "RemoteService";
private Messenger iMessenger;
private final Handler mHandler = new Handler(new Callback()
{
@Override
public boolean handleMessage(Message arg0)
{
switch (arg0.what)
{
case RemoteService.MSG_FROM_CLIENT:
//获得服务进程传递过来的msg
String msg = arg0.getData().getString("msg");
Log.e(TAG, msg);
/** *注意前面设置过msg的replyTo为客户端定义的mHandler */
iMessenger = arg0.replyTo;
Bundle bundle = new Bundle();
bundle.putString("rsp", "rsp from server");
Message message = Message.obtain(null,
RemoteService.MSG_FROM_CLIENT);
message.setData(bundle);
try
{
iMessenger.send(message);
} catch (RemoteException e)
{
e.printStackTrace();
}
break;
default:
break;
}
return false;
}
});
@Override
public IBinder onBind(Intent arg0)
{
return new Messenger(mHandler).getBinder();
}
}
(4)最后就是aidl方式,aidl是处理Android进程间通信的,可以实现一对多的通信,下面通过一个相加求和的例子来讲解
下面是aidl文件,在两个app项目中,需要设置包名一模一样,会在gen包下生成对应的Java文件
package com.example.servicetest;
/** *注意书写规范 *interface 没有 public private 的修饰 *方法也没有public private的修饰 */
interface AIDLSum{
double sum(double d1, double d2);
}
package com.example.servicetest;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class ActivityAidl extends Activity implements OnClickListener {
private Button mButton;
private final String TAG = "ActivityAidl";
private AIDLSum mAidlService;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.service_layout);
initView();
}
private void initView()
{
mButton = (Button) findViewById(R.id.btn_start_service);
mButton.setOnClickListener(this);
}
@Override
public void onClick(View arg0)
{
switch (arg0.getId())
{
case R.id.btn_start_service:
bindService(new Intent(ActivityAidl.this, AIDLService.class),
mConnection, BIND_AUTO_CREATE);
break;
default:
break;
}
}
private final ServiceConnection mConnection = new ServiceConnection()
{
@Override
public void onServiceDisconnected(ComponentName arg0)
{
}
@Override
public void onServiceConnected(ComponentName arg0, IBinder arg1)
{
Log.e(TAG, "----onServiceConnected----");
//asInterface函数可以在gen的aidl对应的java文件中查看
mAidlService = AIDLSum.Stub.asInterface(arg1);
double sum;
try
{
sum = mAidlService.sum(2.0, 5.0);
Log.e(TAG, sum + "");
} catch (RemoteException e)
{
e.printStackTrace();
}
}
};
@Override
protected void onDestroy()
{
super.onDestroy();
unbindService(mConnection);
};
}
最后看看AIDLService.java文件:
package com.example.servicetest;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
public class AIDLService extends Service {
private final String TAG = "AIDLService";
@Override
public IBinder onBind(Intent arg0)
{
Log.e(TAG, "----onBind----");
return stub;
}
//这里是处理逻辑的核心部分,就是实现了aidl中的interface中的接口函数
private final AIDLSum.Stub stub = new AIDLSum.Stub()
{
@Override
public double sum(double d1, double d2) throws RemoteException
{
return d1 + d2;
}
};
}
以上就是service的四种使用场景。希望有所帮助
————————————–向死而生———————————
梅花香自苦寒来