标签:启动方式 简单 xtend can 情况下 dia argument 扑克 top
Service(服务):是一个没有用户界面、可以在后台长期运行且可以执行操作的应用组件。服务可由其他应用组件启动(如:Activity、另一个service)。此外,组件可以绑定到服务,以与之进行交互,甚至是执行进程间通信 (IPC)。例如:服务可以处理网络事务、播放音乐,执行文件 I/O 或与内容提供程序交互,而这一切均可在后台进行。
了解进程的优先级可以帮助你理解服务~
服务:默认运行在主线程。
- 自定义一个服务类继承 android.app.Service;
- 在清单文件中配置 service(AndroidManifest.xml);
- 在服务类中重写方法。
<service android:name=".service.MyCustomService"></service>先上代码
    private Intent startIntent;
    //start方式:开启服务
    public void startOpenService(View v) {
        //创建一个开启服务的Intent对象
        startIntent = new Intent(this, MyCustomService.class);
        this.startService(startIntent); //开启一个服务
    }
    //start方式:关闭服务
    public void startCloseService(View v) {
        if (startIntent != null) {
            this.stopService(startIntent);
            startIntent = null;
        }
    }1. 通过 startService(Intent service)开启服务
2. 通过 stopService(Intent service)关闭服务
特别说明
1. stopService传入的Intent对象,必须和startService传入的Intent对象是同一个对象,才能保证开启的服务被关闭。
2. 应用退出后(应用在后台运作,未被杀死),服务依然会运行中。
3. 当手动杀掉应用进程后,服务将会终止!且该方式不会执行服务的onDestroy()方法。
先上代码
    private Intent bindIntent;
    private MyServiceConnection connection;
    private boolean isSuccess;
    //bind方式:开启服务
    public void bindOpenService(View v) {
        if (!isSuccess) {
            bindIntent = new Intent(this, MyCustomService.class);
            //boolean bindService(Intent service,  //开启服务的意图对象
            //                    ServiceConnection conn, //服务连接对象
            //                    int flags)  //绑定服务操作选项()
            connection = new MyServiceConnection();
            isSuccess = this.bindService(bindIntent, connection, Context.BIND_AUTO_CREATE);
        }
    }
    
    //bind方式:解绑服务
    public void bindCloseService(View v) {
        //void unbindService(ServiceConnection conn)
        if (connection != null) {
            this.unbindService(connection);
            connection = null;
            isSuccess = false;
        }
    }1. 通过 bindService() 开启服务
2. 通过 unbindService() 解绑服务
特别说明
1. 绑定和解绑传递的ServiceConnection对象要保证是同一个对象!
2. isSuccess存储服务绑定成功(true)的状态,当绑定成功之后,避免重复的绑定。因为每次bindService传递的ServiceConnection对象都是new的新对象,unbindService传递的ServiceConnection对象可能会与服务绑定时传递的对象不一致,就会抛出异常!
3. 解绑之后,isSuccess赋值false,就可以再次操作绑定了。
4. bind方式开启的服务是一个隐形的服务,在设置中无法找到(其实现在有些手机定制系统,start方式开启的服务也成了一个隐形服务了)。
5. bind方式开启服务与开启者(Activity),存在着依附关系,在开启者被销毁前,必须解绑bind方式开启的服务,不然会抛出异常!(不求同生,但求同死。)
需求:在Activity中,使用 bind方式 启动一个服务,并调用服务中的方法(模拟一些业务处理)。
分析:流程步骤
- 创建一个服务类,继承 Service。如:MyCustomService;
- 自定义一个服务接口对象类,实现ServiceConnection接口。如:MyServiceConnection;
- 自定义一个中间帮助类,继承Binder类(IBinder实现类)。当服务中的onBind方法被执行的时候,作为返回值。如:MyBinderImpl;
- 自定义一个接口,封装一些中间帮助类对象共有的函数。如:MyBinderInterface。
整个流程代码如下
MyCustomService.class
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
/**
 * 创建一个服务类
 */
public class MyCustomService extends Service {
    @Override
    public IBinder onBind(Intent intent) {
        //该方法:在使用【bind绑定】的方式:开启服务的时候,才会被调用
        Log.e("Service生命周期", "【onBind】");
        //返回值需要一个IBinder接口实现类对象(可以返回自定义实现类对象)
        return new MyBinderInter();
    }
    @Override
    public boolean onUnbind(Intent intent) {
        Log.e("Service生命周期", "【onUnbind】");
        return super.onUnbind(intent);
    }
    @Override
    public void onCreate() {
        super.onCreate();
        //服务第一次创建时调用
        Log.e("Service生命周期", "【onCreate】");
        //获取服务运行线程
        String name = Thread.currentThread().getName();
        long id = Thread.currentThread().getId();
        Log.e("线程", "【Service】" + name + "-" + id);
    }
    
    
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        //每次开启服务(Activity内调用startService()方法)时调用
        Log.e("Service生命周期", "【onStartCommand】");
        return super.onStartCommand(intent, flags, startId);
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        //服务被销毁时调用
        Log.e("Service生命周期", "【onDestroy】");
    }
    
    
    //模拟:定义一些函数,作为业务处理
    public void playPoker() {
        Toast.makeText(this, "玩扑克", Toast.LENGTH_SHORT).show();
    }
    public void playBall() {
        Toast.makeText(this, "打球", Toast.LENGTH_SHORT).show();
    }
    /**
     * 中间帮助类:自定义类继承 Binder(IBinder 接口实现类)
     */
    public class MyBinderInter extends Binder implements MyBinderInterface {
        @Override
        public void callPlayPoker() {
            playPoker();
        }
        @Override
        public void callPlayBall() {
            playBall();
        }
    }
}MyServiceConnection.class
import android.content.ComponentName;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.util.Log;
/**
 * 创建一个服务接口对象类:当服务绑定成功时,可以接收一个中间帮助类对象
 * 当 MyCustomService 中的 onBind 方法返回值不为null时,该服务连接对象类中的方法才会被执行
 */
public class MyServiceConnection implements ServiceConnection {
    private MyCustomService.MyBinderInter myBinderInter;
    @Override
    public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
        //服务绑定成功后执行(onBind执行后执行该方法)  IBinder:中间帮助类对象
        this.myBinderInter = (MyCustomService.MyBinderInter) iBinder;
        Log.e("Service生命周期", "【onServiceConnected】");
    }
    @Override
    public void onServiceDisconnected(ComponentName componentName) {
        //该方法在连接正常关闭的情况下不会被执行,只有在Service被破坏或杀死的情况下执行。
        //如:系统资源不足,需要杀掉该服务,则会执行该方法。
    }
    public void callPlayPoker(){
        if(myBinderInter!=null){
            myBinderInter.callPlayPoker();
        }
    }
    public void callPlayBall(){
        if(myBinderInter!=null){
            myBinderInter.callPlayBall();
        }
    }
}接口:MyBinderInterface
//自定义接口:封装中间帮助类所共有的一些方法
public interface MyBinderInterface {
    //随意定义两个抽象方法,由实现类重写
    void callPlayPoker();
    void callPlayBall();
}ServiceActivity 内调用服务内的方法
public class ServiceActivity extends BaseActivity {
    private Intent bindIntent;
    private MyServiceConnection connection;
    private boolean isSuccess;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_service);
    }
    //bind方式:开启服务
    public void bindOpenService(View v) {
        if (!isSuccess) {
            bindIntent = new Intent(this, MyCustomService.class);
            connection = new MyServiceConnection();
            isSuccess = this.bindService(bindIntent, connection, Context.BIND_AUTO_CREATE);
        }
    }
    public void playPoker(View v) {
        if (connection != null) {
            connection.callPlayPoker();
        }
    }
    public void playBall(View v) {
        if (connection != null) {
            connection.callPlayBall();
        }
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (connection != null) {
            this.unbindService(connection);
            connection = null;
            isSuccess = false;
        }
    }
}关于:bindService和unbindService的源码说明(英文好的小伙伴可以一起学习)
boolean bindService (Intent service, ServiceConnection conn, int flags)
void unbindService (ServiceConnection conn)
参考链接:Google官方文档:Service
PS:期待与大家有更多的交流,谢谢~
标签:启动方式 简单 xtend can 情况下 dia argument 扑克 top
原文地址:https://www.cnblogs.com/io1024/p/11566803.html