Java:如何向父类通知工作完成;Android IntentService销毁时机问题
让我分别来解答你的两个问题:
在Java里,和父类传递工作完成的信号,常用这几种方式,根据场景选择即可:
回调接口:这是最常用的解耦方式。先定义一个回调接口,父类实现这个接口,子类持有父类的引用(或者接口实例),当工作完成时调用接口方法通知父类。
举个简单例子:// 定义回调接口 public interface OnWorkDoneListener { void onWorkCompleted(); } // 父类实现接口 public class ParentClass implements OnWorkDoneListener { public void startChildWork() { ChildClass child = new ChildClass(this); child.doWork(); } @Override public void onWorkCompleted() { System.out.println("父类收到:工作完成了"); } } // 子类持有回调引用,完成时通知 public class ChildClass { private OnWorkDoneListener mListener; public ChildClass(OnWorkDoneListener listener) { mListener = listener; } public void doWork() { // 执行工作逻辑... if (mListener != null) { mListener.onWorkCompleted(); } } }调用父类的protected方法:如果父类和子类耦合度较高,可以在父类定义一个protected的方法(比如
notifyWorkDone()),子类在工作完成时直接调用这个方法。
示例:public class ParentClass { protected void notifyWorkDone() { System.out.println("工作完成的通知收到了"); } } public class ChildClass extends ParentClass { public void doWork() { // 执行工作... notifyWorkDone(); // 直接调用父类方法通知 } }观察者模式:如果是更复杂的多通知场景,可以用Java自带的
Observable和Observer(或者Java 8+的Consumer等函数式接口),子类作为被观察者,父类注册为观察者,工作完成时发送通知。
首先得说,你现在的用法确实偏离了IntentService的设计初衷!IntentService的核心逻辑是:它会自动创建工作线程处理onHandleIntent()里的任务,当所有传入的Intent都处理完后,会自动调用stopSelf()销毁自己。你现在把任务放在onCreate()里启动线程,又没实现onHandleIntent(),相当于把它当成了普通Service在用,自然不会自动停止。
给你两个修正方向,根据你的场景选择:
方案1:按IntentService的正确用法改造
把你的Camera2Video任务移到onHandleIntent()里执行,如果任务是同步的,执行完后IntentService会自动销毁;如果是异步任务,就给Camera2Video加个回调,完成后手动调用stopSelf()。
修正后的代码示例:
// 先给Camera2Video加个回调接口,用于通知工作完成 public interface CameraVideoCallback { void onVideoTaskCompleted(); } public class Camera2Video { private CameraVideoCallback mCallback; public void setCallback(CameraVideoCallback callback) { mCallback = callback; } public void start() { // 这里是你的录制/处理逻辑,当任务完成时触发回调 // 比如录制结束后: if (mCallback != null) { mCallback.onVideoTaskCompleted(); } } // 你的其他方法:closeCamera()、stopBackgroundThread()... } // 修正后的IntentService public class VideoService extends IntentService implements CameraVideoCallback { private Camera2Video mCamera2Video; // 必须显式调用父类的构造方法,传入服务名称 public VideoService() { super("VideoService"); } @Override protected void onHandleIntent(Intent intent) { // 在这里初始化并启动Camera2Video任务 mCamera2Video = new Camera2Video(); mCamera2Video.setCallback(this); mCamera2Video.start(); // 如果是同步任务,这里执行完就会自动停止;异步任务则等待回调 } @Override public void onVideoTaskCompleted() { // 收到任务完成通知,手动停止服务 stopSelf(); } @Override public void onDestroy() { super.onDestroy(); // 在这里做清理工作 mCamera2Video.closeCamera(); mCamera2Video.stopBackgroundThread(); // 其他资源释放... } }
方案2:改用普通Service
如果你根本不需要处理Intent请求,只是需要一个后台服务来运行Camera2Video,那不如直接继承普通的Service,自己管理线程,在任务完成时调用stopSelf()销毁服务。这种情况下,IntentService反而有点“大材小用”了。
总结一下:IntentService的自动销毁是依赖onHandleIntent()处理完所有Intent的逻辑,如果你不用这个方法,它就不会自动停止。按正确用法改造后,就能解决销毁时机的问题啦。
内容的提问来源于stack exchange,提问作者njho

