- 浏览: 912158 次
- 性别:
- 来自: 上海
最新评论
-
liu149339750:
我勒个去,搜到你的博客了,关注!
Android make脚本简记 -
ihopethatwell:
楼主,这个修改时间有个问题,退出修改界面就不保存设置的时间了, ...
Android中如何修改系统时间(应用程序获得系统权限) -
flyar520:
你好...我也遇到屏幕半屏刷成黑屏的问题...但是我的时在开机 ...
Android横屏状态下返回到壁纸界面屏幕刷新问题 -
flyar520:
你好...我也遇到屏幕半屏刷成黑屏的问题...但是我的时在开机 ...
Android横屏状态下返回到壁纸界面屏幕刷新问题 -
taowayi:
推荐android一键反编译神器 apkdec
Android apk反编译
1. Service生命周期
(1)Service生命周期只有onCreate, onStart和onDestroy,没有onResume, onPause和onStop 。如果你在onCreate或onStart做一些很耗时间的事情,最好启动一个线程来完成,因为如果Service是跑在主线程中的,会影响到你的UI操作或者阻塞主线程中的其他事情。
(2)Android系统会尽量保持使用Service的进程尽可能长(Service被启动或者有客户端绑定到Service)。当系统内存变低,系统需要kill现存的进程时,Service的hosting进程的优先级将会在下列的可能中保持更高:
If the service is currently executing code in its onCreate(), onStart(), or onDestroy() methods, then the hosting process will be a foreground process to ensure this code can execute without being killed.
If the service has been started, then its hosting process is considered to be less important than any processes that are currently visible to the user on-screen, but more important than any process not visible. Because only a few processes are generally visible to the user, this means that the service should not be killed except in extreme low memory conditions.
If there are clients bound to the service, then the service's hosting process is never less important than the most important client. That is, if one of its clients is visible to the user, then the service itself is considered to be visible.
(3)大多数时间你的Service是运行的,但在严重的内存压力下它也可能被系统kill。如果是这样,系统会在稍后尝试重新启动这个Service 。 An important consequence of this is that if you implement onStart() to schedule work to be done asynchronously or in another thread, then you may want to write information about that work into persistent storage during the onStart() call so that it does not get lost if the service later gets killed.
Other application components running in the same process as the service (such as an Activity) can, of course, increase the importance of the overall process beyond just the importance of the service itself.
2. Service的调用
(1)Context.startService():Service会经历onCreate -> onStart(如果Service还没有运行,则android先调用onCreate()然后调用onStart();如果Service已经运行,则只调用onStart(),所以一个Service的onStart方法可能会重复调用多次 );stopService的时候直接onDestroy,如果是调用者自己直接退出而没有调用stopService的话,Service会一直在后台运行。该Service的调用者再启动起来后可以通过stopService关闭Service。 注意,多次调用Context.startservice()不会嵌套(即使会有相应的onStart()方法被调用),所以无论同一个服务被启动了多少次,一旦调用Context.stopService()或者stopSelf(),他都会被停止。补充说明:传递给startService()的Intent对象会传递给onStart()方法。调用顺序为:onCreate --> onStart(可多次调用) --> onDestroy。
(2)Context.bindService():Service会经历onCreate() -> onBind(),onBind将返回给客户端一个IBind接口实例,IBind允许客户端回调服务的方法,比如得到Service运行的状态或其他操作。这个时候把调用者(Context,例如Activity)会和Service绑定在一起,Context退出了,Srevice就会调用onUnbind -> onDestroyed相应退出,所谓绑定在一起就共存亡了 。
补充说明:传递给bindService()的Intent对象会传递给onBind(),传递给unbindService()的Intent对象会传递给onUnbind()方法。 调用顺序为:onCreate --> onBind(只一次,不可多次绑定) --> onUnbind --> onDestory。
(3)注意事项:在Service每一次的开启关闭过程中,只有onStart可被多次调用(通过多次startService调用),其他onCreate,onBind,onUnbind,onDestory在一个生命周期中只能被调用一次。还有一点,目前我没有遇到过需要startService和bindService交互使用的情况(我认为不会有这种需求),所以不必去考虑交互的问题,待遇到时再考虑不迟。
(4)BroadcastReceiver只能通过startService启动Service ,因为广播本身生命周期很短,bind的话没有意义:Method bindService can not be called from an BroadcastReceiver component. A pattern you can use to communicate from an BroadcastReceiver to a Service is to call startService(Intent) with the arguments containing the command to be sent, with the service calling its stopSelf(int) method when done executing that command. See the API demo App/Service/Service Start Arguments Controller for an illustration of this. It is okay, however, to use this method from an BroadcastReceiver that has been registered with registerReceiver(BroadcastReceiver, IntentFilter), since the lifetime of this BroadcastReceiver is tied to another object (the one that registered it).
3. 示例代码
(1)调用者Activity
Java代码
1.public class TServiceHolder extends Activity {
2. private boolean isBound;
3. private TService tService;
4. private int statusCode;
5.
6. private ServiceConnection conn = new ServiceConnection() {
7. // Called when a connection to the Service has been established, with the IBinder of the communication channel to the Service.
8. public void onServiceConnected(ComponentName name, IBinder service) {
9. tService = ( (TService.LocalBinder) service ).getService();
10. statusCode = ( (TService.LocalBinder) service ).getStatusCode();
11. Toast.makeText(TServiceHolder.this, "Service Connected", Toast.LENGTH_SHORT).show();
12. }
13.
14. //无法被触发,原因未能找到
15. public void onServiceDisconnected(ComponentName name) {
16. tService = null;
17. Toast.makeText(TServiceHolder.this, "Service DisConnected", Toast.LENGTH_SHORT).show();
18. }
19. };
20. public void onCreate(Bundle savedInstanceState) {
21. super.onCreate(savedInstanceState);
22. setContentView(R.layout.main);
23. initButtons();
24. }
25.
26. private void initButtons() {
27. Button startButton = (Button) findViewById(R.id.startService);
28. Button bindButton = (Button) findViewById(R.id.bindService);
29. Button unbindButton = (Button) findViewById(R.id.unbindService);
30. Button stopButton = (Button) findViewById(R.id.stopService);
31.
32. startButton.setOnClickListener(new Button.OnClickListener() {
33. public void onClick(View v) {
34. Intent i = new Intent(TServiceHolder.this, TService.class);
35. TServiceHolder.this.startService(i);
36. }
37. });
38. bindButton.setOnClickListener(new Button.OnClickListener() {
39. public void onClick(View v) {
40. Intent i = new Intent(TServiceHolder.this, TService.class);
41. TServiceHolder.this.bindService(i, conn, Context.BIND_AUTO_CREATE);
42. isBound = true;
43. }
44. });
45. unbindButton.setOnClickListener(new Button.OnClickListener() {
46. public void onClick(View v) {
47. if (isBound) {
48. TServiceHolder.this.unbindService(conn);
49. isBound = false;
50. }
51. }
52. });
53. stopButton.setOnClickListener(new Button.OnClickListener() {
54. public void onClick(View v) {
55. Intent i = new Intent(TServiceHolder.this, TService.class);
56. TServiceHolder.this.stopService(i);
57. }
58. });
59. }
60.
61.}
public class TServiceHolder extends Activity {
private boolean isBound;
private TService tService;
private int statusCode;
private ServiceConnection conn = new ServiceConnection() {
// Called when a connection to the Service has been established, with the IBinder of the communication channel to the Service.
public void onServiceConnected(ComponentName name, IBinder service) {
tService = ( (TService.LocalBinder) service ).getService();
statusCode = ( (TService.LocalBinder) service ).getStatusCode();
Toast.makeText(TServiceHolder.this, "Service Connected", Toast.LENGTH_SHORT).show();
}
//无法被触发,原因未能找到
public void onServiceDisconnected(ComponentName name) {
tService = null;
Toast.makeText(TServiceHolder.this, "Service DisConnected", Toast.LENGTH_SHORT).show();
}
};
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
initButtons();
}
private void initButtons() {
Button startButton = (Button) findViewById(R.id.startService);
Button bindButton = (Button) findViewById(R.id.bindService);
Button unbindButton = (Button) findViewById(R.id.unbindService);
Button stopButton = (Button) findViewById(R.id.stopService);
startButton.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
Intent i = new Intent(TServiceHolder.this, TService.class);
TServiceHolder.this.startService(i);
}
});
bindButton.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
Intent i = new Intent(TServiceHolder.this, TService.class);
TServiceHolder.this.bindService(i, conn, Context.BIND_AUTO_CREATE);
isBound = true;
}
});
unbindButton.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
if (isBound) {
TServiceHolder.this.unbindService(conn);
isBound = false;
}
}
});
stopButton.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
Intent i = new Intent(TServiceHolder.this, TService.class);
TServiceHolder.this.stopService(i);
}
});
}
} (2)Service
Java代码
1.public class TService extends android.app.Service {
2. private final String TAG = "Service";
3. private final int NOTIFICATION_ID = 1;
4. private NotificationManager nManager;
5.
6. private LocalBinder localBinder = new LocalBinder();
7. private int statusCode;
8.
9. public void onCreate() {
10. Log.i(TAG, "Service.onCreate");
11. nManager = (NotificationManager) getSystemService(android.content.Context.NOTIFICATION_SERVICE);
12. showNotification();
13. }
14. private void showNotification() {
15. Notification n = new Notification(R.drawable.face_1, "Service启动", System.currentTimeMillis());
16. PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, TServiceHolder.class), 0);
17. n.setLatestEventInfo(this, "任务标题", "任务内容", contentIntent);
18. nManager.notify(NOTIFICATION_ID, n); // 任务栏启动
19. }
20. public void onStart(Intent intent, int startId) {
21. Log.i(TAG, "Service.onStart");
22. }
23. public IBinder onBind(Intent intent) {
24. Log.i(TAG, "Service.onBind");
25. /*
26. * 调用者和Service间是依靠IBinder对象进行通信的,Service的onBind()返回的IBinder对象传递给调用者中ServiceConnection对象的onServiceConnected()方法(以参数形式接收);
27. * TService的调用者就可以利用这个IBinder获得TService对象,进而对TService进行操作控制;
28. * TService的调用者也可以利用这个IBinder获得其他信息,比如TService的状态statusCode。
29. */
30. return localBinder;
31. }
32. /*
33. * 当应用程序bind一个Service后,该应用程序和Service之间就能进行互相通信,通常,这种通信的完成依靠于我们定义的一些接口,例如下面的LocalBinder。
34. */
35. class LocalBinder extends Binder {
36. public TService getService() {
37. return TService.this; // Service本身
38. }
39. public int getStatusCode() {
40. return statusCode;
41. }
42. }
43. public void onRebind(Intent i) {
44. Log.i(TAG, "Service.onRebind");
45. }
46. public boolean onUnbind(Intent i) {
47. Log.i(TAG, "Service.onUnbind");
48. return false;
49. }
50. public void onDestroy() {
51. nManager.cancel(NOTIFICATION_ID); // 任务栏关闭
52. Log.i(TAG, "Service.onDestroy");
53. }
54.}
public class TService extends android.app.Service {
private final String TAG = "Service";
private final int NOTIFICATION_ID = 1;
private NotificationManager nManager;
private LocalBinder localBinder = new LocalBinder();
private int statusCode;
public void onCreate() {
Log.i(TAG, "Service.onCreate");
nManager = (NotificationManager) getSystemService(android.content.Context.NOTIFICATION_SERVICE);
showNotification();
}
private void showNotification() {
Notification n = new Notification(R.drawable.face_1, "Service启动", System.currentTimeMillis());
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, TServiceHolder.class), 0);
n.setLatestEventInfo(this, "任务标题", "任务内容", contentIntent);
nManager.notify(NOTIFICATION_ID, n); // 任务栏启动
}
public void onStart(Intent intent, int startId) {
Log.i(TAG, "Service.onStart");
}
public IBinder onBind(Intent intent) {
Log.i(TAG, "Service.onBind");
/*
* 调用者和Service间是依靠IBinder对象进行通信的,Service的onBind()返回的IBinder对象传递给调用者中ServiceConnection对象的onServiceConnected()方法(以参数形式接收);
* TService的调用者就可以利用这个IBinder获得TService对象,进而对TService进行操作控制;
* TService的调用者也可以利用这个IBinder获得其他信息,比如TService的状态statusCode。
*/
return localBinder;
}
/*
* 当应用程序bind一个Service后,该应用程序和Service之间就能进行互相通信,通常,这种通信的完成依靠于我们定义的一些接口,例如下面的LocalBinder。
*/
class LocalBinder extends Binder {
public TService getService() {
return TService.this; // Service本身
}
public int getStatusCode() {
return statusCode;
}
}
public void onRebind(Intent i) {
Log.i(TAG, "Service.onRebind");
}
public boolean onUnbind(Intent i) {
Log.i(TAG, "Service.onUnbind");
return false;
}
public void onDestroy() {
nManager.cancel(NOTIFICATION_ID); // 任务栏关闭
Log.i(TAG, "Service.onDestroy");
}
}
4. 与远程Service通信(进程间Service通信)
如何两个进程间的Service需要进行通信,则需要把对象序列化后进行互相发送。
Android提供了一个 AIDL (Android接口定义语言)工具来处理序列化和通信。这种情况下Service需要以aidl文件的方式提供服务接口,AIDL工具将生成一个相应的java接口,并且在生成的服务接口中包含一个功能调用的stub服务桩类。Service的实现类需要去继承这个 stub服务桩类。Service的onBind方法会返回实现类的对象,之后你就可以使用它了,参见下例:
先创建一个IMyRemoteService.aidl文件,内容如下:
package com.wissen.testApp;
interface IMyRemoteService {
int getStatusCode();
}
如果你正在使用eclipse的 Android插件,则它会根据这个aidl文件生成一个Java接口类。生成的接口类中会有一个内部类Stub类,你要做的事就是去继承该Stub类:
package com.wissen.testApp;
class RemoteService implements Service {
int statusCode;
@Override
public IBinder onBind(Intent arg0) {
return myRemoteServiceStub;
}
private IMyRemoteService.Stub myRemoteServiceStub = new IMyRemoteService.Stub() {
public int getStatusCode() throws RemoteException {
return 0;
}
};
…
}
当客户端应用连接到这个Service时,onServiceConnected方法将被调用,客户端就可以获得IBinder对象。参看下面的客户端onServiceConnected方法:
…
ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
IMyRemoteService myRemoteService = IMyRemoteService.Stub.asInterface(service);
try {
statusCode = myRemoteService.getStatusCode();
} catch(RemoteException e) {
// handle exception
}
Log.i(”INFO”, “Service bound “);
}
…
};
(1)Service生命周期只有onCreate, onStart和onDestroy,没有onResume, onPause和onStop 。如果你在onCreate或onStart做一些很耗时间的事情,最好启动一个线程来完成,因为如果Service是跑在主线程中的,会影响到你的UI操作或者阻塞主线程中的其他事情。
(2)Android系统会尽量保持使用Service的进程尽可能长(Service被启动或者有客户端绑定到Service)。当系统内存变低,系统需要kill现存的进程时,Service的hosting进程的优先级将会在下列的可能中保持更高:
If the service is currently executing code in its onCreate(), onStart(), or onDestroy() methods, then the hosting process will be a foreground process to ensure this code can execute without being killed.
If the service has been started, then its hosting process is considered to be less important than any processes that are currently visible to the user on-screen, but more important than any process not visible. Because only a few processes are generally visible to the user, this means that the service should not be killed except in extreme low memory conditions.
If there are clients bound to the service, then the service's hosting process is never less important than the most important client. That is, if one of its clients is visible to the user, then the service itself is considered to be visible.
(3)大多数时间你的Service是运行的,但在严重的内存压力下它也可能被系统kill。如果是这样,系统会在稍后尝试重新启动这个Service 。 An important consequence of this is that if you implement onStart() to schedule work to be done asynchronously or in another thread, then you may want to write information about that work into persistent storage during the onStart() call so that it does not get lost if the service later gets killed.
Other application components running in the same process as the service (such as an Activity) can, of course, increase the importance of the overall process beyond just the importance of the service itself.
2. Service的调用
(1)Context.startService():Service会经历onCreate -> onStart(如果Service还没有运行,则android先调用onCreate()然后调用onStart();如果Service已经运行,则只调用onStart(),所以一个Service的onStart方法可能会重复调用多次 );stopService的时候直接onDestroy,如果是调用者自己直接退出而没有调用stopService的话,Service会一直在后台运行。该Service的调用者再启动起来后可以通过stopService关闭Service。 注意,多次调用Context.startservice()不会嵌套(即使会有相应的onStart()方法被调用),所以无论同一个服务被启动了多少次,一旦调用Context.stopService()或者stopSelf(),他都会被停止。补充说明:传递给startService()的Intent对象会传递给onStart()方法。调用顺序为:onCreate --> onStart(可多次调用) --> onDestroy。
(2)Context.bindService():Service会经历onCreate() -> onBind(),onBind将返回给客户端一个IBind接口实例,IBind允许客户端回调服务的方法,比如得到Service运行的状态或其他操作。这个时候把调用者(Context,例如Activity)会和Service绑定在一起,Context退出了,Srevice就会调用onUnbind -> onDestroyed相应退出,所谓绑定在一起就共存亡了 。
补充说明:传递给bindService()的Intent对象会传递给onBind(),传递给unbindService()的Intent对象会传递给onUnbind()方法。 调用顺序为:onCreate --> onBind(只一次,不可多次绑定) --> onUnbind --> onDestory。
(3)注意事项:在Service每一次的开启关闭过程中,只有onStart可被多次调用(通过多次startService调用),其他onCreate,onBind,onUnbind,onDestory在一个生命周期中只能被调用一次。还有一点,目前我没有遇到过需要startService和bindService交互使用的情况(我认为不会有这种需求),所以不必去考虑交互的问题,待遇到时再考虑不迟。
(4)BroadcastReceiver只能通过startService启动Service ,因为广播本身生命周期很短,bind的话没有意义:Method bindService can not be called from an BroadcastReceiver component. A pattern you can use to communicate from an BroadcastReceiver to a Service is to call startService(Intent) with the arguments containing the command to be sent, with the service calling its stopSelf(int) method when done executing that command. See the API demo App/Service/Service Start Arguments Controller for an illustration of this. It is okay, however, to use this method from an BroadcastReceiver that has been registered with registerReceiver(BroadcastReceiver, IntentFilter), since the lifetime of this BroadcastReceiver is tied to another object (the one that registered it).
3. 示例代码
(1)调用者Activity
Java代码
1.public class TServiceHolder extends Activity {
2. private boolean isBound;
3. private TService tService;
4. private int statusCode;
5.
6. private ServiceConnection conn = new ServiceConnection() {
7. // Called when a connection to the Service has been established, with the IBinder of the communication channel to the Service.
8. public void onServiceConnected(ComponentName name, IBinder service) {
9. tService = ( (TService.LocalBinder) service ).getService();
10. statusCode = ( (TService.LocalBinder) service ).getStatusCode();
11. Toast.makeText(TServiceHolder.this, "Service Connected", Toast.LENGTH_SHORT).show();
12. }
13.
14. //无法被触发,原因未能找到
15. public void onServiceDisconnected(ComponentName name) {
16. tService = null;
17. Toast.makeText(TServiceHolder.this, "Service DisConnected", Toast.LENGTH_SHORT).show();
18. }
19. };
20. public void onCreate(Bundle savedInstanceState) {
21. super.onCreate(savedInstanceState);
22. setContentView(R.layout.main);
23. initButtons();
24. }
25.
26. private void initButtons() {
27. Button startButton = (Button) findViewById(R.id.startService);
28. Button bindButton = (Button) findViewById(R.id.bindService);
29. Button unbindButton = (Button) findViewById(R.id.unbindService);
30. Button stopButton = (Button) findViewById(R.id.stopService);
31.
32. startButton.setOnClickListener(new Button.OnClickListener() {
33. public void onClick(View v) {
34. Intent i = new Intent(TServiceHolder.this, TService.class);
35. TServiceHolder.this.startService(i);
36. }
37. });
38. bindButton.setOnClickListener(new Button.OnClickListener() {
39. public void onClick(View v) {
40. Intent i = new Intent(TServiceHolder.this, TService.class);
41. TServiceHolder.this.bindService(i, conn, Context.BIND_AUTO_CREATE);
42. isBound = true;
43. }
44. });
45. unbindButton.setOnClickListener(new Button.OnClickListener() {
46. public void onClick(View v) {
47. if (isBound) {
48. TServiceHolder.this.unbindService(conn);
49. isBound = false;
50. }
51. }
52. });
53. stopButton.setOnClickListener(new Button.OnClickListener() {
54. public void onClick(View v) {
55. Intent i = new Intent(TServiceHolder.this, TService.class);
56. TServiceHolder.this.stopService(i);
57. }
58. });
59. }
60.
61.}
public class TServiceHolder extends Activity {
private boolean isBound;
private TService tService;
private int statusCode;
private ServiceConnection conn = new ServiceConnection() {
// Called when a connection to the Service has been established, with the IBinder of the communication channel to the Service.
public void onServiceConnected(ComponentName name, IBinder service) {
tService = ( (TService.LocalBinder) service ).getService();
statusCode = ( (TService.LocalBinder) service ).getStatusCode();
Toast.makeText(TServiceHolder.this, "Service Connected", Toast.LENGTH_SHORT).show();
}
//无法被触发,原因未能找到
public void onServiceDisconnected(ComponentName name) {
tService = null;
Toast.makeText(TServiceHolder.this, "Service DisConnected", Toast.LENGTH_SHORT).show();
}
};
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
initButtons();
}
private void initButtons() {
Button startButton = (Button) findViewById(R.id.startService);
Button bindButton = (Button) findViewById(R.id.bindService);
Button unbindButton = (Button) findViewById(R.id.unbindService);
Button stopButton = (Button) findViewById(R.id.stopService);
startButton.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
Intent i = new Intent(TServiceHolder.this, TService.class);
TServiceHolder.this.startService(i);
}
});
bindButton.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
Intent i = new Intent(TServiceHolder.this, TService.class);
TServiceHolder.this.bindService(i, conn, Context.BIND_AUTO_CREATE);
isBound = true;
}
});
unbindButton.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
if (isBound) {
TServiceHolder.this.unbindService(conn);
isBound = false;
}
}
});
stopButton.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
Intent i = new Intent(TServiceHolder.this, TService.class);
TServiceHolder.this.stopService(i);
}
});
}
} (2)Service
Java代码
1.public class TService extends android.app.Service {
2. private final String TAG = "Service";
3. private final int NOTIFICATION_ID = 1;
4. private NotificationManager nManager;
5.
6. private LocalBinder localBinder = new LocalBinder();
7. private int statusCode;
8.
9. public void onCreate() {
10. Log.i(TAG, "Service.onCreate");
11. nManager = (NotificationManager) getSystemService(android.content.Context.NOTIFICATION_SERVICE);
12. showNotification();
13. }
14. private void showNotification() {
15. Notification n = new Notification(R.drawable.face_1, "Service启动", System.currentTimeMillis());
16. PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, TServiceHolder.class), 0);
17. n.setLatestEventInfo(this, "任务标题", "任务内容", contentIntent);
18. nManager.notify(NOTIFICATION_ID, n); // 任务栏启动
19. }
20. public void onStart(Intent intent, int startId) {
21. Log.i(TAG, "Service.onStart");
22. }
23. public IBinder onBind(Intent intent) {
24. Log.i(TAG, "Service.onBind");
25. /*
26. * 调用者和Service间是依靠IBinder对象进行通信的,Service的onBind()返回的IBinder对象传递给调用者中ServiceConnection对象的onServiceConnected()方法(以参数形式接收);
27. * TService的调用者就可以利用这个IBinder获得TService对象,进而对TService进行操作控制;
28. * TService的调用者也可以利用这个IBinder获得其他信息,比如TService的状态statusCode。
29. */
30. return localBinder;
31. }
32. /*
33. * 当应用程序bind一个Service后,该应用程序和Service之间就能进行互相通信,通常,这种通信的完成依靠于我们定义的一些接口,例如下面的LocalBinder。
34. */
35. class LocalBinder extends Binder {
36. public TService getService() {
37. return TService.this; // Service本身
38. }
39. public int getStatusCode() {
40. return statusCode;
41. }
42. }
43. public void onRebind(Intent i) {
44. Log.i(TAG, "Service.onRebind");
45. }
46. public boolean onUnbind(Intent i) {
47. Log.i(TAG, "Service.onUnbind");
48. return false;
49. }
50. public void onDestroy() {
51. nManager.cancel(NOTIFICATION_ID); // 任务栏关闭
52. Log.i(TAG, "Service.onDestroy");
53. }
54.}
public class TService extends android.app.Service {
private final String TAG = "Service";
private final int NOTIFICATION_ID = 1;
private NotificationManager nManager;
private LocalBinder localBinder = new LocalBinder();
private int statusCode;
public void onCreate() {
Log.i(TAG, "Service.onCreate");
nManager = (NotificationManager) getSystemService(android.content.Context.NOTIFICATION_SERVICE);
showNotification();
}
private void showNotification() {
Notification n = new Notification(R.drawable.face_1, "Service启动", System.currentTimeMillis());
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, TServiceHolder.class), 0);
n.setLatestEventInfo(this, "任务标题", "任务内容", contentIntent);
nManager.notify(NOTIFICATION_ID, n); // 任务栏启动
}
public void onStart(Intent intent, int startId) {
Log.i(TAG, "Service.onStart");
}
public IBinder onBind(Intent intent) {
Log.i(TAG, "Service.onBind");
/*
* 调用者和Service间是依靠IBinder对象进行通信的,Service的onBind()返回的IBinder对象传递给调用者中ServiceConnection对象的onServiceConnected()方法(以参数形式接收);
* TService的调用者就可以利用这个IBinder获得TService对象,进而对TService进行操作控制;
* TService的调用者也可以利用这个IBinder获得其他信息,比如TService的状态statusCode。
*/
return localBinder;
}
/*
* 当应用程序bind一个Service后,该应用程序和Service之间就能进行互相通信,通常,这种通信的完成依靠于我们定义的一些接口,例如下面的LocalBinder。
*/
class LocalBinder extends Binder {
public TService getService() {
return TService.this; // Service本身
}
public int getStatusCode() {
return statusCode;
}
}
public void onRebind(Intent i) {
Log.i(TAG, "Service.onRebind");
}
public boolean onUnbind(Intent i) {
Log.i(TAG, "Service.onUnbind");
return false;
}
public void onDestroy() {
nManager.cancel(NOTIFICATION_ID); // 任务栏关闭
Log.i(TAG, "Service.onDestroy");
}
}
4. 与远程Service通信(进程间Service通信)
如何两个进程间的Service需要进行通信,则需要把对象序列化后进行互相发送。
Android提供了一个 AIDL (Android接口定义语言)工具来处理序列化和通信。这种情况下Service需要以aidl文件的方式提供服务接口,AIDL工具将生成一个相应的java接口,并且在生成的服务接口中包含一个功能调用的stub服务桩类。Service的实现类需要去继承这个 stub服务桩类。Service的onBind方法会返回实现类的对象,之后你就可以使用它了,参见下例:
先创建一个IMyRemoteService.aidl文件,内容如下:
package com.wissen.testApp;
interface IMyRemoteService {
int getStatusCode();
}
如果你正在使用eclipse的 Android插件,则它会根据这个aidl文件生成一个Java接口类。生成的接口类中会有一个内部类Stub类,你要做的事就是去继承该Stub类:
package com.wissen.testApp;
class RemoteService implements Service {
int statusCode;
@Override
public IBinder onBind(Intent arg0) {
return myRemoteServiceStub;
}
private IMyRemoteService.Stub myRemoteServiceStub = new IMyRemoteService.Stub() {
public int getStatusCode() throws RemoteException {
return 0;
}
};
…
}
当客户端应用连接到这个Service时,onServiceConnected方法将被调用,客户端就可以获得IBinder对象。参看下面的客户端onServiceConnected方法:
…
ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
IMyRemoteService myRemoteService = IMyRemoteService.Stub.asInterface(service);
try {
statusCode = myRemoteService.getStatusCode();
} catch(RemoteException e) {
// handle exception
}
Log.i(”INFO”, “Service bound “);
}
…
};
评论
1 楼
haking
2011-07-14
同时使用startService和bindService是正常的。当你想和service通信而且想保持在context退出后service仍然运行的情况下。就可以这样使用。
发表评论
-
Android JNI 编程常见小问题
2015-09-08 11:31 1184extern "C" { jint Jav ... -
Android ServiceManager注册自定义service
2015-08-19 09:53 4091当我们要使用android的系统服务时,一般都是使用Conte ... -
Android ALMP 架设web服务器配置
2014-10-08 18:48 1419随着信息时代的发展,智能手机已经越来越普及。下面本文将带大家把 ... -
Android UiAutomator 自动化测试
2014-07-04 17:39 9865一、一个BUG引发的问题 ... -
Android XP MTP支持
2014-03-18 16:41 2219家里电脑是win7,连上直接豌豆荚装驱动就好了。但单位的XP却 ... -
Android Launcher2 icon大小修改
2012-08-16 19:12 5990不同分辨率、不同屏幕的不同设备,android 原生的Laun ... -
android 浏览器APN切换
2012-04-16 16:42 2265业务需求:有些链接需 ... -
android 浏览器全屏显示
2012-04-16 16:40 4840业务需求:浏览器设置中支持全屏显示的功能。 分析:只需要在 ... -
Android MD5校验码的生成与算法实现
2012-03-05 15:05 20303在Java中,java.security.MessageDi ... -
Android View的xml属性
2012-02-27 13:25 2790java.lang.Object andro ... -
Android Gallery3D源码学习总结(三)——Cache缓存及数据处理流程
2011-12-29 11:04 4635第一,在应用程序中有三个线程存在:主线程(随activity的 ... -
Android Gallery3d源码学习总结(二)——绘制流程drawThumbnails
2011-12-29 11:02 2863此函数控制相册表格页 ... -
Android Gallery 3D 特效精华
2011-12-29 10:45 5262Android Gallery 3D 特效精华 一、布 ... -
Android Gallery3d源码学习总结(一)——绘制流程drawFocusItems
2011-12-29 10:42 2674显示单张图片相关的输入变量 int selecte ... -
Android:AppWidget,PendingIntent,RemoteViews用法
2011-11-25 10:09 5814什么是AppWidget?AppWidget就是我们平常在 ... -
Android软件汉化/精简/去广告教程
2011-08-23 12:32 2860前言: 现在随处都可以找到功能强大的汉化工具,操作简 ... -
Android ListView页眉页脚效果
2011-07-06 14:07 2634大家都知道,在我们调用ListView的addFooterVi ... -
Android 获取设备信息
2011-06-22 21:09 7891)android 获取设备型号、OS版本号: imp ... -
Android 应用安装设置
2011-05-31 16:18 1838应用程序的默认安装位置以及是否可移动取决于该程序的开发者的配置 ... -
Android Activity去除标题栏和状态栏
2011-05-31 13:10 40423一、在代码中设置 public void onCreate( ...
相关推荐
android service 简单实例代码 . binder继承一个接口,实现方法。
Demo android service toast 第一个版本
android service使用的小demo 包括startService stopService bindService unbindService 两种开启、关闭service的小demo
Android Service下载文件
关于Android Service的简单实例:属于start service类型,而不是bound service。
Android Service下载,EventBus更新界面,取代传统的用Handler或者广播更新界面,代码更加优雅,更加简洁
Android Service被关闭后自动重启,解决被异常kill 服务
android service 学习(下) ,共两部分
Android Service使用,包括Start Service和bind Service启动方式。Service与Acvitity互相传递数据
android Service中onStartCommand返回值.txt 有四种返回值,分别代表的含义
这是Pro Android学习系列中Android Service部分的例子源代码。相关学习笔记见:http://blog.csdn.net/flowingflying/article/details/6212512
通过Messenger实现Android Service更新UI
主要介绍了Android Service 服务不被杀死的妙招的相关资料,需要的朋友可以参考下
Android Service Demo
android aidl service
android service 源码 学习
android service 关于android中service的简单例子 适合初学者