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 ");
}
}