ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
## 第六天.AndroidService ## ### 6.1Service概述 ### #### 6.1.1 Service概念及用途 #### 服务是运行在后台的一段代码。 不是进程,也不是线程。 可以运行在它自己的进程,也可以运行在其他应用程序进程的上下文(context)里面,这取决于自身的需要。 Android中的服务,它与Activity不同,它是不能与用户交互的,不能自己启动的,运行在后台的程序。 媒体播放器的服务,当用户退出媒体选择用户界面,仍然希望音乐依然可以继续播放,这就是由服务(service)来保证当用户界面关闭时音乐继续播放的。 比如当我们一个应用的数据是通过网络获取的,不同时间的数据是不同的,这时候我们可以用Service在后台定时更新,而不用每打开应用的时候在去获取。 ### 6.2 Service生命周期 #### + onCreate() 在服务被创建时调用,该方法只会被调用一次,无论调用多少次startService()或bindService()方法,服务也只被创建一次。 + onStart() 只有采用Context.startService()方法启动服务时才会回调该方法。该方法在服务开始运行时被调用。多次调用startService()方法尽管不会多次创建服务,但onStart() 方法会被多次调用。 + onDestroy() 服务被终止时调用。 + onBind() 只有采用Context.bindService()方法启动服务时才会回调该方法。该方法在调用者与服务绑定时被调用,当调用者与服务已经绑定,多次调用Context.bindService()方法并不会导致该方法被多次调用。 + onUnbind() 只有采用Context.bindService()方法启动服务时才会回调该方法。该方法在调用者与服务解除绑定时被调用。 startService后,即使调用startService的进程结束了Service仍然还存在,直到有进程调用stopService,或者Service自己自杀(stopSelf())。 bindService后,Service就和调用bindService的进程同生共死了,也就是说当调用bindService的进程死了,那么它bind的Service也要跟着被结束,当然期间也可以调用unbindservice让Service结束。 两种方式混合使用时,比如说你startService了,我bindService了,那么只有你stopService了而且我也unbindservice了,这个Service才会被结束。 ### 6.3启动与停止Service ### #### 6.3.1 Service开发步骤 #### 第一步:继承Service类 ``` public class MyService extends Service { } ``` 第二步:在AndroidManifest.xml文件中的节点里对服务进行配置: 服务不能自己运行,使用startService()方法启用服务,调用者与服务之间没有关连,即使调用者退出了,服务仍然运行。使用bindService()方法启用服务,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止,大有“不求同时生,必须同时死”的特点。 如果打算采用Context.startService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onStart()方法。如果调用startService()方法前服务已经被创建,多次调用startService()方法并不会导致多次创建服务,但会导致多次调用onStart()方法。采用startService()方法启动的服务,只能调用Context.stopService()方法结束服务,服务结束时会调用onDestroy()方法。 如果打算采用Context.bindService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onBind()方法。这个时候调用者和服务绑定在一起,调用者退出了,系统就会先调用服务的onUnbind()方法,接着调用onDestroy()方法。如果调用bindService()方法前服务已经被绑定,多次调用bindService()方法并不会导致多次创建服务及绑定(也就是说onCreate()和onBind()方法并不会被多次调用)。如果调用者希望与正在绑定的服务解除绑定,可以调用unbindService()方法,调用该方法也会导致系统调用服务的onUnbind()-->onDestroy()方法。 #### 6.3.2 采用startService()启动服务 #### 采用Context.startService()方法启动服务的代码如下: ``` public class HelloActivity extends Activity { public void onCreate(Bundle savedInstanceState) { ...... Button button =(Button) this.findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener(){ public void onClick(View v) { Intent intent = new Intent(HelloActivity.this, SMSService.class); startService(intent); }}); } } ``` #### 6.3.3 采用bindService()启动服务 #### 采用Context.startService()方法启动服务的代码如下: ``` public class HelloActivity extends Activity { ServiceConnection conn = new ServiceConnection() { public void onServiceConnected(ComponentName name, IBinder service) { } public void onServiceDisconnected(ComponentName name) { } }; public void onCreate(Bundle savedInstanceState) { Button button =(Button) this.findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener(){ public void onClick(View v) { Intent intent = new Intent(HelloActivity.this, SMSService.class); bindService(intent, conn, Context.BIND_AUTO_CREATE); //unbindService(conn);//解除绑定 }}); } } ``` #### 6.3.4 Service服务演示 #### 1. 新建一个Android工程ServiceDemo 2. 修改main.xml代码,增加二个按钮 3. 新建一个Service,命名为MyService.java 4. 新建ServiceDemo.java 5. 配置AndroidManifest.xml 6. 执行上述工程, 用Logcat查看日志 7. 按HOME键进入Settings(设置)àApplications(应用)àRunningServices(正在运行的服务) **main.xml** ``` <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:id="@+id/text" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> <Button android:id="@+id/startservice" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="startService" /> <Button android:id="@+id/stopservice" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="stopService" /> </LinearLayout> ``` **MyService.java** ```` public class MyService extends Service { //定义个一个Tag标签 private static final String TAG = "MyService"; //一个Binder类,用在onBind() 方法里,这样Activity那边可以获取到 private MyBinder mBinder = new MyBinder(); public IBinder onBind(Intent intent) { Log.e(TAG, "start IBinder~~~"); return mBinder; } public void onCreate() { Log.e(TAG, "start onCreate~~~"); super.onCreate(); } public void onStart(Intent intent, int startId) { Log.e(TAG, "start onStart~~~"); super.onStart(intent, startId); } ``` ``` public void onDestroy() { Log.e(TAG, "start onDestroy~~~"); super.onDestroy(); } public boolean onUnbind(Intent intent) { Log.e(TAG, "start onUnbind~~~"); return super.onUnbind(intent); } public String getSystemTime(){ Time t = new Time(); t.setToNow(); return t.toString(); } public class MyBinder extends Binder{ MyService getService() { return MyService.this; } } } ``` **ServiceDemo.java** ``` public class ServiceDemo extends Activity implements OnClickListener { private MyService mMyService; private TextView mTextView; private Button startServiceButton; private Button stopServiceButton; private Context mContext; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); setupViews(); } ``` ``` public void setupViews(){ mContext = ServiceDemo.this; mTextView = (TextView)findViewById(R.id.text); startServiceButton = (Button)findViewById(R.id.startservice); stopServiceButton = (Button)findViewById(R.id.stopservice); startServiceButton.setOnClickListener(this); stopServiceButton.setOnClickListener(this); } ``` ``` public void onClick(View v) { if(v == startServiceButton){ Intent i = new Intent(); i.setClass(ServiceDemo.this, MyService.class); mContext.startService(i); }else if(v == stopServiceButton){ Intent i = new Intent(); i.setClass(ServiceDemo.this, MyService.class); mContext.stopService(i); } } } ``` **AndroidManifest.xml** ``` <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.lxt008" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".ServiceDemo" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name=".MyService" android:exported="true"></service> </application> <uses-sdk android:minSdkVersion="7" /> </manifest> ``` ### 6.4Notification通知 ### 如果需要查看消息,可以拖动状态栏到屏幕下方即可查看消息。 发送消息的代码如下: ``` //获取通知管理器 NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); int icon = android.R.drawable.stat_notify_chat; long when = System.currentTimeMillis(); //新建一个通知,指定其图标和标题 //第一个参数为图标,第二个参数为标题,第三个为通知时间 Notification notification = new Notification(icon, null, when); Intent openintent = new Intent(this, OtherActivity.class); //当点击消息时就会向系统发送openintent意图 PendingIntent contentIntent = PendingIntent.getActivity(this, 0, openintent, 0); notification.setLatestEventInfo(this, “标题”, “我是内容", contentIntent); mNotificationManager.notify(0, notification); ``` #### 6.4.1 Android中的通知(Notification) #### ### 6.5案例分析 ### 参考案例:NotificationDemo [源代码下载](http://www.apkbus.com/forum.php?mod=viewthread&tid=83334)