package com.zjw.myservice3; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.View; import android.widget.Button; import butterknife.BindView; import butterknife.ButterKnife; import butterknife.OnClick; //10.3 p349 服务的基本用法 //10.3.1 p349 定义一个服务 //新建一个服务new->Service->Service 勾选Exportd(是否允许除了当前进程之外的其他程序访问这个服务),Enable(是否启用) /* MyService extends Service onBind()是Service中唯一的抽象方法,必须在子类实现 */ /* Service常用重写的方法: 1.onCreate():服务创建时调用 2.onStartCommand():每次服务启动时调用 3.onDestroy():服务销毁时调用 一般情况,如果希望服务一启动就立刻执行,用2,销毁3 */ //10.3.2 p352 启动和停止服务 //主要借助Intent实现 //布局:两个Button,启动和停止服务 //找控件用的黄油刀 //10.3.3 p355 活动和服务进行通信 /* 活动启动服务后服务会一直处于运行状态,但活动控制不了服务具体运行逻辑 借助onBind()方法可以使活动和服务关系更紧密 */ /* 目标: MyService里提供一个下载功能,然后活动可以决定何时开始下载以及随时查看下载进度(具体实现只打log) 思路:创建一个专门的Binder对象来对下载功能进行管理 */ //布局新增两个Button,绑定与解绑 /* bindService()三个参数: 参数一:Intent对象 参数二:ServiceConnection实例 参数三:标志位,传入BIND_AUTO_CREATE表示在活动和服务进行绑定后自动创建服务, 使服务onCreate()执行,onStartCommand()不执行 */ //MyService可以和任一个活动进行绑定,绑定后都可以获取相同DownloadBinder实例 //10.4 p359服务的生命周期 /* 当调用了startService(),又调用bindService(),要同时调用stopService(),unbindService()才能停止服务 */ //10.5 p359 服务的更多技巧 //10.5.1 p359 使用前台服务 /* 当系统出现内存不足情况,可能回收后台服务,可以考虑使用前台服务 最大区别:会一直有一个正在运行的图标在系统的状态栏显示,下拉状态栏后可以看到更加详细的信息 */ //修改MyService代码,在onCreate()里加上通知 // startForeground()方法会让MyService变为一个前台服务,并在系统状态栏显示出来 //10.5.2 p361 使用IntentService /* 如果直接在服务里处理耗时操作,容易出现ANR(Application Not Responding) 需要开启新线程来处理耗时操作 @Override public int onStartCommand(Intent intent, int flags, int startId) {//每次服务启动时调用 new Thread(new Runnable(){ @Override public void run(){ } }).start(); return super.onStartCommand(intent, flags, startId); } 但是服务一旦启动,会一直运行,直到调用stopService或stopSelf() 如果需要运行完自动销毁: @Override public int onStartCommand(Intent intent, int flags, int startId) {//每次服务启动时调用 new Thread(new Runnable(){ @Override public void run(){ //处理具体的逻辑 stopSelf(); } }).start(); return super.onStartCommand(intent, flags, startId); } */ //为了创建一个异步、会自动停止的服务,使用IntentService类 /* 使用流程: 1.新建MyIntentService类继承自IntentService 提供无参构造,必须调用父类有参构造 实现抽象方法onHandleIntent(),这个方法已经是在子线程中运行,并且会在运行结束后自动停止 */ //布局里再加一个Button public class BaseUseOfService extends AppCompatActivity { @BindView(R.id.btn_start_service) Button mBtnStartService; @BindView(R.id.btn_stop_service) Button mBtnStopService; @BindView(R.id.btn_bind_service) Button mBtnBindService; @BindView(R.id.btn_unbind_service) Button mBtnUnbindService; @BindView(R.id.btn_start_intent_service) Button mBtnStartIntentService; private MyService.DownloadBinder mDownloadBinder; private ServiceConnection mServiceConnection = new ServiceConnection() { //服务成功绑定的时候调用 @Override public void onServiceConnected(ComponentName name, IBinder service) { mDownloadBinder = (MyService.DownloadBinder) service; mDownloadBinder.startDownload(); mDownloadBinder.getProcess(); } //服务解绑的时候调用 @Override public void onServiceDisconnected(ComponentName name) { } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_base_use_of_service); ButterKnife.bind(this); } @OnClick({R.id.btn_start_service, R.id.btn_stop_service, R.id.btn_bind_service, R.id.btn_unbind_service,R.id.btn_start_intent_service}) public void onViewClicked(View view) { switch (view.getId()) { case R.id.btn_start_service://启动服务 Intent startIntent = new Intent(BaseUseOfService.this, MyService.class); startService(startIntent); break; case R.id.btn_stop_service://停止服务 Intent stopIntent = new Intent(BaseUseOfService.this, MyService.class); stopService(stopIntent); break; case R.id.btn_bind_service://绑定服务 Intent bindIntent = new Intent(BaseUseOfService.this, MyService.class); bindService(bindIntent, mServiceConnection, BIND_AUTO_CREATE);//绑定服务 break; case R.id.btn_unbind_service://解绑服务 unbindService(mServiceConnection); break; case R.id.btn_start_intent_service://启动MyIntentService服务 //打印当前线程 Log.d("zjw", "onViewClicked: "+Thread.currentThread().getName()); Intent intentIntent = new Intent(BaseUseOfService.this, MyIntentService.class); startService(intentIntent); break; default: break; } } }
package com.zjw.myservice3; import android.app.Notification; import android.app.PendingIntent; import android.app.Service; import android.content.Intent; import android.graphics.BitmapFactory; import android.os.Binder; import android.os.IBinder; import android.support.v7.app.NotificationCompat; import android.util.Log; public class MyService extends Service { private DownloadBinder mDownloadBinder=new DownloadBinder(); class DownloadBinder extends Binder{ public void startDownload(){ Log.d("zjw", "startDownload: "); } public int getProcess(){ Log.d("zjw", "getProcess: "); return 0; } } public MyService() { } @Override public IBinder onBind(Intent intent) { return mDownloadBinder; } @Override public void onCreate() {//服务创建时调用 super.onCreate(); Log.d("zjw", "onCreate: "); //10.5.1 p359 使用前台服务 Intent intent=new Intent(this,BaseUseOfService.class); PendingIntent pendingIntent=PendingIntent.getActivity(this,0,intent,0);//实现通知点击效果 Notification notification=new NotificationCompat.Builder(this) .setContentTitle("This is content title") .setContentText("This is content text") .setWhen(System.currentTimeMillis()) .setSmallIcon(R.mipmap.ic_launcher) .setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher)) .setContentIntent(pendingIntent) .build(); startForeground(1,notification);//参数:id,Notification对象 } @Override public int onStartCommand(Intent intent, int flags, int startId) {//每次服务启动时调用 Log.d("zjw", "onStartCommand: "); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() {//服务销毁时调用 super.onDestroy(); Log.d("zjw", "onDestroy: "); } }
package com.zjw.myservice3; import android.app.IntentService; import android.content.Intent; import android.support.annotation.Nullable; import android.util.Log; /** * Created by hp on 2017/7/27. */ public class MyIntentService extends IntentService { public MyIntentService() { super("MyIntentService");//调用父类有参构造 } //这个方法已经是在子线程中运行,并且会在运行结束后自动停止 @Override protected void onHandleIntent(@Nullable Intent intent) { //打印当前线程 Log.d("zjw", "onHandleIntent: "+Thread.currentThread().getName()); } @Override public void onDestroy() { super.onDestroy(); Log.d("zjw", "MyIntentService:onDestroy "); } }