刚开始看Android,对service理解有错的地方,请大家猛评论。。。
service android应用程序中事务处理的地方。
有两种service:
第一种:用startService()启动的service
第二种:用bindService绑定的service
第一种:继承Service类,并需要重写onBind(),它的生命周期,onCreate()-->onStartCommand()-->onDestroy()
在onCreate()中可以初始化一些值(根据实际情况而定)
onStartCommand()中用来真正的处理一些事务逻辑
onDestroy() 用来处理Service(服务)关闭时的一些东西,如:关闭一些Service运行时候的所占用的一些资源
这个Service用stopService()来进行关闭
可以好多组件来启动该Service,可是只有一个Service运行。当关闭activity时,该服务继续运行,直到调用stopService()服务才终止。
MainAcitivity.java
package com.jiajai.exampleservicetest;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBar;
import android.support.v4.app.Fragment;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.os.Build;
public class MainActivity extends ActionBarActivity {
private Button button1;
private Button button2;
private OnClickListener listener = new OnClickListener(){
public void onClick(View v){
Intent intent = new Intent(MainActivity.this, ExampleService.class);
switch(v.getId()){
case R.id.button1:
startService(intent);
break;
case R.id.button2:
stopService(intent);
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.myactivity);
button1 = (Button)findViewById(R.id.button1);
button2 = (Button)findViewById(R.id.button2);
button1.setOnClickListener(listener);
button2.setOnClickListener(listener);
// if (savedInstanceState == null) {
// getSupportFragmentManager().beginTransaction()
// .add(R.id.container, new PlaceholderFragment()).commit();
// }
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container,
false);
return rootView;
}
}
}
ExampleService.java
package com.jiajai.exampleservicetest;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
public class ExampleService extends Service {
private static final String TAG = "ExampleService";
@Override
public void onCreate() {
Log.i(TAG, "ExampleService->onCreate");
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "ExampleService->onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
Log.i(TAG, "ExampleService->onDestroy");
super.onDestroy();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
第二种:继承Service类,需要在其内部写一个继承Binder的内部类且写出该内部类的实例, 并在onBind()返回该内部类的实例。
用bindService()来绑定Service,unbindService()来解除绑定
生命周期:onCreate()-->onBind()-->onUnbind-->onDestroy()
bindService(intent, conn, BIND_AUTO_CREATE)
conn是ServiceConnection的实例
且通过ServiceConnection中onServiceConnected()方法来与绑定的Service进行联系,并调用Service中我们实际用到的一些事务处理的方法。。。
BinderAcitivity.java
package com.jiajai.exampleservicetest;
import com.jiajai.exampleservicetest.BinderService.MyBinder;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class BinderActivity extends ActionBarActivity {
private Button button1;
private Button button2;
private Boolean isConnected = false;
private OnClickListener listener = new OnClickListener(){
public void onClick(View v){
switch(v.getId()){
case R.id.button1:
bindService();
break;
case R.id.button2:
unBind();
break;
default:
break;
}
}
};
public void bindService(){
Intent intent = new Intent(BinderActivity.this, BinderService.class);
bindService(intent, conn, Context.BIND_AUTO_CREATE);
}
public void unBind(){
if(isConnected){
unbindService(conn);
}
System.out.println("unBind");
}
private ServiceConnection conn = new ServiceConnection(){
public void onServiceConnected(ComponentName name, IBinder service) {
MyBinder myBinder = (MyBinder)service;
BinderService binderService = myBinder.gerService();
binderService.Method();
isConnected = true;
}
@Override
public void onServiceDisconnected(ComponentName name) {
isConnected = false;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.binder);
button1 = (Button)findViewById(R.id.button1);
button2 = (Button)findViewById(R.id.button2);
button1.setOnClickListener(listener);
button2.setOnClickListener(listener);
}
}
BinderService.java
package com.jiajai.exampleservicetest;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
public class BinderService extends Service {
private static final String TAG = "BinderService";
private MyBinder myBinder = new MyBinder();
public class MyBinder extends Binder{
public BinderService gerService(){
return BinderService.this;
}
}
@Override
public IBinder onBind(Intent intent) {
return myBinder;
}
public void Method(){
Log.i(TAG, "BinderService->method");
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
System.out.println("BinderService->onDestroy");
}
}
补:
1:onStartCommand()返回值
onStartCommand()方法必须返回一个整数,这个整数是一个描述了在系统的杀死事件中,系统应该如何继续这个服务的值(虽然你能够修改这个值,但是IntentService处理还是为你提供了默认实现)。从onStartCommand()方法中返回的值必须是以下常量:
START_NOT_STICKY
如果系统在onStartCommand()方法返回之后杀死这个服务,那么直到接受到新的Intent对象,这个服务才会被重新创建。这是最安全的选项,用来避免在不需要的时候运行你的服务。
START_STICKY
如果系统在onStartCommand()返回后杀死了这个服务,系统就会重新创建这个服务并且调用onStartCommand()方法,但是它不会重新传递最后的Intent对象,系统会用一个null的Intent对象来调用onStartCommand()方法,在这个情况下,除非有一些被发送的Intent对象在等待启动服务。这适用于不执行命令的媒体播放器(或类似的服务),它只是无限期的运行着并等待工作的到来。
START_REDELIVER_INTENT
如果系统在onStartCommand()方法返回后,系统就会重新创建了这个服务,并且用发送给这个服务的最后的Intent对象调用了onStartCommand()方法。任意等待中的Intent对象会依次被发送。这适用于那些应该立即恢复正在执行的工作的服务,如下载文件。
2:绑定服务为什么需要Binder内部类
Android 实现绑定服务,是通过onBind()方法实现的,而它返回的是IBinder对象,所以需要继承Binder的内部类。。。相当于把Service封装成Binder对象进行传递。。。
3:Service多线程
如果不需要同时处理多个线程,可以用IntentService来处理多线程
如果需要同时处理多个线程,则需要继承Service
类IntentService可以完成以下工作:
Ø 创建一个工作线程来处理所有发送到onStartCommand()的请求(Intent),从而应用的主线程分开
Ø 创建一个工作队列来逐个处理每个请求,从而无需考虑多线程编程。
Ø 在处理完所有请求后终止Service的运行,你无需调用stopService()来终止Service
Ø 提供onBind()的缺省实现,返回null
Ø 提供onStartCommand()的缺省实现,将接受到的Intent发送到工作队列中,然后调用你的onHandleIntent()实现
所以,只需要提供onHandleIntent()来处理发过来的Intent当然你可能还需要实现Service的一个简单的构造函数。。。
ExampleIntentActivity.java
package com.jiajai.exampleservicetest;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class ExampleIntentActivity extends ActionBarActivity {
private Button button1;
private Button button2;
private Intent intent;
private OnClickListener listener = new OnClickListener(){
public void onClick(View v){
switch(v.getId()){
case R.id.button1:
intent = new Intent(ExampleIntentActivity.this, MyService.class);
System.out.println("主线程id: " + Thread.currentThread().getId());
startService(intent);
break;
case R.id.button2:
intent = new Intent(ExampleIntentActivity.this, MyIntentService.class);
System.out.println("主线程id: " + Thread.currentThread().getId());
startService(intent);
break;
default:
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.intent);
button1 = (Button)findViewById(R.id.button1);
button2 = (Button)findViewById(R.id.button2);
button1.setOnClickListener(listener);
button2.setOnClickListener(listener);
}
}
MyService.java
package com.jiajai.exampleservicetest;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
public class MyService extends Service {
@Override
public void onCreate() {
super.onCreate();
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
new MyThread().start();
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
private class MyThread extends Thread{
@Override
public void run() {
try{
System.out.println("MyService的线程id: " + Thread.currentThread().getId());
System.out.println("文件下载。。。");
Thread.sleep(2000);
}catch(Exception e){
e.printStackTrace();
}
}
}
}
MyIntentService.java
package com.jiajai.exampleservicetest;
import android.app.IntentService;
import android.content.Intent;
public class MyIntentService extends IntentService {
public MyIntentService() {
super("MyIntentService");
}
@Override
protected void onHandleIntent(Intent intent) {
System.out.println("MyService的线程id: " + Thread.currentThread().getId());
System.out.println("文件下载。。。");
try{
Thread.sleep(2000);
}catch(Exception e){
e.printStackTrace();
}
}
}
4:bindService中的参数
-
第一个bindService()的参数是一个明确指定了要绑定的service的Intent.
-
第二个参数是ServiceConnection对象.
-
第三个参数是一个标志,它表明绑定中的操作.它一般应是BIND_AUTO_CREATE,这样就会在service不存在时创建一个.其它可选的值是BIND_DEBUG_UNBIND和BIND_NOT_FOREGROUND,不想指定时设为0即可.。