文章目录
1.service
在Android开发中,Service 是一个可以在后台长时间运行的组件,用于执行耗时操作或执行那些不需要与用户界面直接交互的任务。Service 不依赖于用户界面,即使用户切换到其他应用,Service 仍然可以继续运行。
Service 的主要用途
- 后台任务:执行耗时操作,如下载文件、播放音乐等。
 - 跨进程通信:通过 AIDL 实现跨进程通信(IPC)。
 - 定时任务:定期执行某些任务,如定时同步数据。
 - 保持连接:维持与服务器的长连接,如实时聊天应用。
 
Service生命周期

- onCreate():当 Service 第一次被创建时调用。
 - onStartCommand(Intent intent, int flags, int startId):每当通过 startService() 方法启动 Service 时调用。
 - onBind(Intent intent):每当通过 bindService() 方法绑定到 Service 时调用。
 - onUnbind(Intent intent):当所有客户端都解除绑定时调用。
 - onDestroy():当 Service 被销毁时调用。
 
2.startService
循环打印日志Service:
            
            
              java
              
              
            
          
          public class MyService extends Service {
    private static final String TAG = "ning";
    private ExecutorService executorService;
    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "MyService onCreate");
        // 创建一个单线程的ExecutorService
        executorService = Executors.newSingleThreadExecutor();
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "MyService onStartCommand");
        // 提交一个任务到线程池,周期性地打印日志
        executorService.submit(() -> {
            while (true) {
                Log.d(TAG, "MyService logging at " + System.currentTimeMillis());
                try {
                    Thread.sleep(1000); // 每秒打印一次日志
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        return START_STICKY; // 服务被系统杀死后自动重启
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "MyService onDestroy");
        // 关闭线程池
        if (executorService != null) {
            executorService.shutdownNow();
        }
    }
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.d(TAG, "MyService onBind");
        return null;
    }
}
        
3.bindService
            
            
              java
              
              
            
          
          public class ServiceBindActivity extends AppCompatActivity {
    private Button btn_bind;
    private Button btn_cancel;
    private Button btn_status;
    private static final String TAG = "ning";
    private MyBindService myBindService;
    private boolean isBound = false;
    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d(TAG, "onServiceConnected");
            MyBindService.LocalBinder binder = (MyBindService.LocalBinder) service;
            myBindService = binder.getService();
            isBound = true;
            // 调用 Service 的方法
            myBindService.doSomething();
        }
        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d(TAG, "onServiceDisconnected");
            isBound = false;
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_service_bind);
        btn_bind = findViewById(R.id.btn_bind);
        btn_cancel = findViewById(R.id.btn_cancel);
        btn_status = findViewById(R.id.btn_status);
        Intent intent = new Intent(this, MyBindService.class);
        btn_bind.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 绑定 Service
                bindService(intent, connection, Context.BIND_AUTO_CREATE);
            }
        });
        btn_cancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 解绑 Service
                unbindService(connection);
            }
        });
        btn_status.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 获取 Service 状态
                Log.d(TAG, "Service status: " + (myBindService == null ? "null" : "not null"));
            }
        });
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 解绑 Service
        if (isBound) {
            unbindService(connection);
            isBound = false;
        }
    }
}
        
            
            
              java
              
              
            
          
          public class MyBindService extends Service {
    private static final String TAG = "ning";
    private final IBinder binder = new LocalBinder();
    public class LocalBinder extends Binder {
        MyBindService getService() {
            return MyBindService.this;
        }
    }
    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "MyBoundService onCreate");
    }
    @Override
    public IBinder onBind(Intent intent) {
        Log.d(TAG, "MyBoundService onBind");
        return binder;
    }
    @Override
    public boolean onUnbind(Intent intent) {
        Log.d(TAG, "MyBoundService onUnbind");
        return super.onUnbind(intent);
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "MyBoundService onDestroy");
    }
    public void doSomething() {
        Log.d(TAG, "MyBoundService doSomething called");
    }
}
        4.区别
在 Android 中,startService 和 bindService 都是用来启动和管理 Service 的方法,但它们的使用场景和行为有所不同。下面是它们的主要区别和使用场景:
startService
功能
- 启动型 
Service:通过startService方法启动的Service是启动型Service,主要用于执行一次性的后台任务,如下载文件、上传数据等。 - 生命周期 :
Service会一直运行,直到它自己调用stopSelf方法或者外部调用stopService方法将其停止。 - 回调方法 :主要使用 
onStartCommand方法来处理启动请求。 
使用场景
- 后台任务:执行耗时操作,如下载文件、上传数据、处理大量数据等。
 - 定时任务:定期执行某些任务,如定时同步数据。
 - 无需与 
Service交互 :不需要与Service进行持续的通信,只需要启动Service并让它完成任务。 
示例代码
            
            
              java
              
              
            
          
          // 启动 Service
Intent intent = new Intent(this, MyStartedService.class);
startService(intent);
// 停止 Service
stopService(intent);
        bindService
功能
- 绑定型 
Service:通过bindService方法启动的Service是绑定型Service,主要用于组件之间的交互,如Activity与Service之间的数据交换。 - 生命周期 :
Service会一直运行,直到所有绑定的客户端都解除绑定。当最后一个客户端解除绑定时,Service会调用onUnbind方法,并最终调用onDestroy方法。 - 回调方法 :主要使用 
onBind方法来返回一个IBinder对象,用于客户端与Service之间的通信。 
使用场景
- 持续交互 :需要与 
Service进行持续的通信,如播放音乐、实时数据更新等。 - 跨进程通信 :通过 
AIDL实现跨进程通信。 - 资源共享 :多个组件共享同一个 
Service的资源。 
示例代码
            
            
              java
              
              
            
          
          // 定义 ServiceConnection
private ServiceConnection connection = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        Log.d("TAG", "onServiceConnected");
        LocalBinder binder = (LocalBinder) service;
        myBoundService = binder.getService();
        isBound = true;
        // 调用 Service 的方法
        myBoundService.doSomething();
    }
    @Override
    public void onServiceDisconnected(ComponentName name) {
        Log.d("TAG", "onServiceDisconnected");
        isBound = false;
    }
};
// 绑定 Service
Intent intent = new Intent(this, MyBoundService.class);
bindService(intent, connection, Context.BIND_AUTO_CREATE);
// 解绑 Service
if (isBound) {
    unbindService(connection);
    isBound = false;
}
        总结
- 
startService:- 用于启动一次性的后台任务。
 Service会一直运行,直到显式停止。- 主要使用 
onStartCommand方法处理任务。 - 适用于不需要与 
Service进行持续通信的场景。 
 - 
bindService:- 用于组件之间的持续交互。
 Service的生命周期与绑定的客户端相关,当所有客户端解除绑定时,Service会停止。- 主要使用 
onBind方法返回IBinder对象进行通信。 - 适用于需要与 
Service进行持续通信的场景。