Android开发之startService和bindService详解

  • Service(服务)在Android 中是在后台运行的。服务的运行不需要任何用户界面。
    启动服务有两种方式,分别是startService和bindService。
    下面我们就来介绍一下startService和bindService的用法和区别。

startService

创建一个工程ServiceTest,布局文件中添加两个按钮,一个开启服务,一个停止服务。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/btn_start_service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="开启服务" />

    <Button
        android:id="@+id/btn_stop_service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="停止服务" />
</LinearLayout>
创建一个类MyService继承Service。然后重写其onCreate(),onStartCommand(),
onDestroy()方法,在方法中加入Log打印日志。如下:
public class MyService extends Service {
    public static final String TAG = "MyService";
    @Override
    public IBinder onBind(Intent intent) {
        return myBinder;
    }

    //在服务创建的时候调
    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "onCreate ......");
    }

    //在每次服务启动的时候调用
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "onStartCommand ......");
        return super.onStartCommand(intent, flags, startId);
    }

    //在服务销毁的时候调用。
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy ......");
    }
}
当然,别忘了在Manifest.xml文件中配置。
 <service android:name=".MyService"></service>
MainActivity中代码如下。

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private Button btn_start_service;
    private Button btn_stop_service;

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

        btn_start_service = (Button) this.findViewById(R.id.btn_start_service);
        btn_stop_service = (Button) this.findViewById(R.id.btn_stop_service);

        btn_start_service.setOnClickListener(this);
        btn_stop_service.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.btn_start_service:
                Intent intent = new Intent(this,MyService.class);
                //开启服务
                startService(intent);
                break;
            case R.id.btn_stop_service:
                Intent intent2 = new Intent(this,MyService.class);
                //停止服务
                stopService(intent2);
                break;
        }
    }
}
运行程序到模拟器上,点击 开启服务按钮,然后到设置--> 应用 -->正在运行 查看,效果如下。

服务

MyService中的onCreate()和 onStartCommand()方法都执行了,日志如下:
1555-1555/com.example.servicetest D/MyService: onCreate ......
1555-1555/com.example.servicetest D/MyService: onStartCommand ......
然后再点击多次开启服务按钮,发现只有onStartCommand()方法执行了。

日志

点击停止服务按钮,onDestroy()方法已经执行了。

结果

查看 设置--> 应用 -->正在运行 发现服务已经被销毁了。

销毁

  • 小总结,使用startService开启服务的方式,可以使服务长期运行在后台。

bindService

前边我们介绍了startService,下面我们来聊一聊bindService。
往布局文件中添加2个按钮。
  <Button
        android:id="@+id/btn_bind_service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="绑定服务" />
    <Button
        android:id="@+id/btn_unbind_service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="解绑服务" />
修改MyService中代码,创建MyBinder类继承BInder,并自定义一个startGame()方法,打印Log。
并将MyBinder 的实例对象在onBind()方法中返回回去。
 private  MyBinder myBinder = new MyBinder();
    class MyBinder extends Binder{
        public void startGame(){
            Log.d(TAG,"我是服务里边的方法,startGame ......");
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        return myBinder;
    }
MainActivity中使用bindService需要借助到ServiceConnection这个类。
重写其绑定成功onServiceConnected()和绑定失败onServiceDisconnected()的方法。
并将onServiceConnected()方法中的service强转为自己写的MyBinder,并调用startGame()方法。
public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private Button btn_start_service;
    private Button btn_stop_service;
    private Button btn_bind_service;
    private Button btn_unbind_service;
    private MyService.MyBinder myBinder;
    boolean flag = false;

    private ServiceConnection connection = new ServiceConnection() {
        //成功绑定的时候调用
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
        //强转
            myBinder =   (MyService.MyBinder) service;
            //调用服务里边的方法
            myBinder.startGame();
            flag = true ;
        }
        /**
         * 连接正常关闭的情况下是不会被调用的, 
         * 该方法只在Service 被破坏了或者被杀死的时候调用。
         */
        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

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

        btn_start_service = (Button) this.findViewById(R.id.btn_start_service);
        btn_stop_service = (Button) this.findViewById(R.id.btn_stop_service);
        btn_bind_service = (Button) this.findViewById(R.id.btn_bind_service);
        btn_unbind_service = (Button) this.findViewById(R.id.btn_unbind_service);

        btn_start_service.setOnClickListener(this);
        btn_stop_service.setOnClickListener(this);
        btn_bind_service.setOnClickListener(this);
        btn_unbind_service.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.btn_start_service:
                Intent intent = new Intent(this,MyService.class);
                //开启服务
                startService(intent);
                break;
            case R.id.btn_stop_service:
                Intent intent2 = new Intent(this,MyService.class);
                //停止服务
                stopService(intent2);
                break;
            case R.id.btn_bind_service:
                Intent bindIntent = new Intent(this, MyService.class);
                //  绑定服务
                bindService(bindIntent,connection,BIND_AUTO_CREATE);
                break;
            case R.id.btn_unbind_service:
               if (flag){
                    //解绑服务
                    unbindService(connection);
                    flag = false;
                }
                break;
        }
    }
}
运行程序,点击绑定服务按钮,发现MyBinder中的startGame()方法已经被调用了。
5829-5829/com.example.servicetest D/MyService: onCreate ......
5829-5829/com.example.servicetest D/MyService: 我是服务里边的方法,startGame ......
多次点击 绑定服务按钮 ,发现Log信息并没有变化,说明只能绑定一次。
查看 设置--> 应用 -->正在运行 发现服务并没有被创建。

服务

然后点击 解绑服务 按钮 ,执行了onDestroy()方法。

效果

  • 小总结,bindService只能调用服务中的方法,不能启动服务让其长期运行在后台。

startService和bindService组合使用

经过上边的例子,我们已经了解了两者的区别,那么现在我有个想法,
我既想让服务长期运行在后台,又想调用服务里边的方法,该怎么办呢?
我们可以将startService和bindService组合到一起来使用。
还是使用刚才那个例子,运行程序。
先点击 开启服务按钮, 再点击 绑定服务按钮 ,Log如下。

Log

查看 设置--> 应用 -->正在运行 发现服务已经被创建了。

效果

我们想要的功能就实现了,既让服务运行在后台,又调到了服务里边的方法。
销毁服务的时候需要 点击解绑服务 的按钮才可以销毁服务。
以上就是startService和bindService的用法和区别。如有错误请指出,谢谢!
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值