Android学习--四大组件之一Service

第一种Service

定义

  • 安卓四大组件之一,级别和activity相当
  • 长时间运行在后台,不可见的,没有界面的组件
  • 运行在主线程中的
  • 可以跨进程调用

为什么要使用Service

  • 大部分病毒利用了Service的特点,可以在后台完成预设的功能;
  • 作为Android工程师,至少需要了解Service是如何在后台完成预设功能。

两种启动方式

  1. startService
  2. bindService

使用startService方式启动Service的步骤

  1. 新建类继承Service
  2. 重写onCreate方法
  3. 实现onBind抽象方法
  4. 重写onStartCommand方法
  5. 重写onDestory方法
  6. 在AndroidManifest中注册Service
  7. 在有Context环境中通过startService启动Service
  8. 在有Context环境中通过stopService停止Service

使用startService方式启动Service的总结(优缺点)

  • onCreat只执行一次 运行在主线程,耗时操作需另开子线程
  • 通过Intent传参,在onStatCommand中接收参数
  • 无法获得Service参数,不能直接操作Service的属性的方法
  • 调用stopService方法,Service会执行
  • 优点:使用简单
  • 缺点:无法获得Service参数,不能直接操作Service的属性的方法

代码展示

avtivity_main:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.homework.activity.serviceactivity.MainActivity">
    <Button
        android:id="@+id/start_btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Start Service" />
    <Button
        android:id="@+id/stop_btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Stop Service" />
</LinearLayout>

MyService:

public class MyService extends Service {

    //1,创建时启动,只执行一次
    @Override
    public void onCreate() {
        super.onCreate();
        //打印获得子线程名
        Log.e("Service"+Thread.currentThread().getName(), "onCreate()……");
    }

    //2,执行很多次
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        //打印获得子线程名
        Log.e("Service"+Thread.currentThread().getName(),"onStartCommand() ……");

        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    //打印获得子线程名
                    Log.e("Service" + Thread.currentThread().getName(), i + "***");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();

        return super.onStartCommand(intent, flags, startId);
    }

    //3
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.e("Service", "onDestroy() ……");
    }
    //4
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

MainActivity:

public class MainActivity extends Activity implements View.OnClickListener {

    private Button startBtn;
    private Button stopBtn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        startBtn=findViewById(R.id.start_btn);
        stopBtn=findViewById(R.id.stop_btn);
        startBtn.setOnClickListener(this);
        stopBtn.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.start_btn:
                Intent startIntent = new Intent(this, MyService.class);
                startService(startIntent);
                break;
            case R.id.stop_btn:
                Intent stopIntent = new Intent(this, MyService.class);
                stopService(stopIntent);
                break;
            default:
                break;
        }
    }
}

使用bindService方式启动Service的步骤

  1. 新建类继承Service
  2. 重写onCreatr方法
  3. 实现onBind抽象方法(需要返回一个bind子类对象)
  4. 重写onUnbind方法
  5. 重写onDestory方法
  6. 在AndroidManifest中注册Service(使用标签注册 )
  7. 在有Context环境中通过ServiceConnection
  8. 在有Context环境中通过bindService绑定Service
  9. 在有Context环境中通过unbindService解绑Service

使用bindService方式启动Service的总结(优缺点)

在Context上下文调用此方法即可触发绑定Service,此方法需要三个参数。

  • Intent对象,用于传参;
  • ServiceConnection接口对象;
  • flag标识,代表如何绑定Service,常用的flag是Context.BIND_AUTO_CREATE,代表Service不存在时创建。

优点:想要获得Service对象,并操作它的属性和方法,需要使用bindService;
缺点:使用bindService启动Service步骤比较繁琐。

代码展示:

activity_main:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.homework.activity.bindservice.MainActivity">


    <Button
        android:id="@+id/bind_btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="绑定按钮"/>

    <Button
        android:id="@+id/unbind_btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="解绑按钮"/>
    <Button
        android:id="@+id/to_lisi_btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="前往李四页面"/>
</LinearLayout>

MainActivity:

//新建MainService继承Service
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private String TAG="MainActivity";
    private Button bindbtn;
    private Button unbindbtn;
    private Button tolistbtn;

//创建ServiceConnection,实现两个方法,onServiceConnected,onServiceDisconnected
//在onServiceConnected中,转换为Guanjia类型,调用getService,拿到TextService对象,TextService.fly运行
    private ServiceConnection serviceConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.e(TAG,"onServiceConnected");
            //通过管家的中介作用,拿到MyService对象
            Myservice myservice = ((Myservice.Guanjia)service).getServiceObject();
            myservice.fly();
            //  System.out.println("connected");
        }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        Log.e(TAG,"onServiceDisconnected");
        // System.out.println("onDisConnected");
         }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        bindID();

        // 从5.0开始,谷歌要求必须使用显示intent启动service

    }
    private void bindID() {
        bindbtn = findViewById(R.id.bind_btn);
        unbindbtn = findViewById(R.id.unbind_btn);
        tolistbtn=findViewById(R.id.to_lisi_btn);
        bindbtn.setOnClickListener(this);
        unbindbtn.setOnClickListener(this);
        tolistbtn.setOnClickListener(this);
    }

//设置监听,Intent,联系Guanjia,bindService(intent,serviceconnectio,自动连接)
    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.bind_btn:
                Intent intent=new Intent(this,Myservice.class);
                bindService(intent, serviceConnection,BIND_AUTO_CREATE);
                break;
            case R.id.unbind_btn:
                unbindService(serviceConnection);
                break;
            case R.id.to_lisi_btn:
                Intent intent1=new Intent(this,LisiActivity.class);
                startActivity(intent1);
                break;
        }
    }
}

MyService:

//创建Guanjia得到当前Service对象
public class Myservice extends Service {

    private String TAG="Myservice";

    private Guanjia guanjia=new Guanjia();

    public class Guanjia extends Binder{
        //作用:得到当前Service的对象
        public Myservice getServiceObject(){
            return Myservice.this;
        }
    }

//定义fly方法,打log(开飞机)
    public void fly(){
        Log.e(TAG,"打飞机");
    }
    @Override
    public IBinder onBind(Intent intent) {
        Log.e(TAG,"执行onBind方法...");
        return guanjia;
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Log.e(TAG,"执行onUnBind方法...");
        return super.onUnbind(intent);
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.e(TAG,"执行onCreate方法");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.e(TAG,"执行onDestroy方法");
    }
}

第二种Service,IntentService

使用IntentService的总结(与Service的区别)

  • 继承于Service并处理异步任务的一个类
  • 在IntentService内有一个工作线程来执行耗时操作//重点区别
  • 此线程无需我们控制和维护
  • 当多次启动时,会以队列的形式,逐一执行
  • 当执行完耗时操作后,此Service会自动停止

使用IntentService方式启动Service的步骤

  1. 新建类继承IntentService
  2. 实现父类的构造方法
  3. 重写onHandleIntent方法
  4. 重写Oncreat方法
  5. 重写onDestory方法
  6. 在AndroidManifest中注册Service
  7. 在有Context环境中实现ServiceConnection接口
  8. 在有Context环境中通过startService绑定Service
  9. 在有Context环境中通过stopService解绑Service

onHandleIntent

  • 需要执行的耗时操作放在此方法中执行
  • 此方法会新开线程,不会在main线程中执行

//bindServise跳转到IntentService页面

activity_lisi:


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.homework.activity.bindservice.LisiActivity">

    <Button
        android:id="@+id/list_bind_btn"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:text="绑定Service"/>
    <Button
        android:id="@+id/list_unbind_btn"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:text="解绑Service"/>
</LinearLayout>

MyIntentService:

public class MyIntentService extends IntentService{
    /**
     * Creates an IntentService.  Invoked by your subclass's constructor.
     *
     * @param name Used to name the worker thread, important only for debugging.
     */
    public MyIntentService(String name) {
        super(name);
    }

    public MyIntentService(){
        super("");//当前线程名

    }

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        for(int i=0;i<10;i++){
            try {
                Thread.sleep(1000);
                Log.e("MyIntentService",i+"***");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

LisiActivity:

public class LisiActivity extends AppCompatActivity implements View.OnClickListener{
    private Button bindBtn;
    private Button unBindBtn;

    private String TAG="ListActicity";

    private ServiceConnection connection=new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.e(TAG,"onServiceConnected*****************");
            Myservice myservice=((Myservice.Guanjia) service).getServiceObject();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.e(TAG,"onServiceDisconnected*******************");
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_lisi);

        bindID();
    }

    private void bindID() {
        bindBtn=findViewById(R.id.list_bind_btn);
        unBindBtn=findViewById(R.id.list_unbind_btn);
        bindBtn.setOnClickListener(this);
        unBindBtn.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.list_bind_btn:
//                Intent intent=new Intent(this,Myservice.class);
//                bindService(intent,connection,BIND_AUTO_CREATE);
                Intent intent=new Intent(this,MyIntentService.class);
                startService(intent);
                break;
            case R.id.list_unbind_btn:
                unbindService(connection);
                break;
        }
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值