刚开始看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; } } }
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); } }
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); } }
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(); } } } }
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即可.。