-1

是否可以在BroadcastReceiveronReceive方法中使用HandlerThread进一步在主 UI 线程上启动服务?

我的目标是在onReceive方法中使用HandlerThread,以便服务在单独的线程中启动。

但不知道如何实现。

有什么提示吗?

谢谢

编辑:服务类

public class BackgroundVideoRecorder extends Service implements SurfaceHolder.Callback {

public  WindowManager windowManager;
public SurfaceView surfaceView;
public Camera camera = null;
public MediaRecorder mediaRecorder = null;


@Override
public IBinder onBind(Intent intent) {
    return null;
}



@Override
public void onCreate() {

    // Create new SurfaceView, set its size to 1x1, move it to the top left corner and set this service as a callback
    windowManager = (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
    surfaceView = new SurfaceView(getApplicationContext());
    WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(
            1, 1,
            WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
            WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
            PixelFormat.TRANSLUCENT
    );
    layoutParams.gravity = Gravity.LEFT | Gravity.TOP;
    windowManager.addView(surfaceView, layoutParams);
    surfaceView.getHolder().addCallback(this);

}

// Method called right after Surface created (initializing and starting MediaRecorder)
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {

    try {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (ContextCompat.checkSelfPermission(getApplicationContext(), CAMERA) == PackageManager.PERMISSION_GRANTED) {
                camera = Camera.open();
            }else{
                // should show permission
            }

        } else {
            camera = Camera.open();
        }
        mediaRecorder = new MediaRecorder();
        camera.unlock();

        mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());
        mediaRecorder.setCamera(camera);
        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
        mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
        mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_1080P));


        mediaRecorder.setOutputFile(
                Environment.getExternalStorageDirectory() + "/" +
                        DateFormat.format("yyyy-MM-dd_kk-mm-ss", new Date().getTime()) +
                        ".mp4"
        );

        try {
            mediaRecorder.prepare();
        } catch (Exception e) {
        }
        mediaRecorder.start();

    } catch (Exception e) {

    }


}

// Stop recording and remove SurfaceView
@Override
public void onDestroy() {

    mediaRecorder.stop();
    mediaRecorder.reset();
    mediaRecorder.release();

    camera.lock();
    camera.release();

    windowManager.removeView(surfaceView);

}


@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) {
}

@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
}


}

我认为我没有正确使用服务。请帮忙。

EDIT2:Logcat

 08/11 18:00:20: Launching app
$ adb push     F:\AndroidStudioWorkspace\MyApplication2\app\build\outputs\apk\app-debug.apk    /data/local/tmp/com.example.jatin.myapplication2
$ adb shell pm install -r "/data/local/tmp/com.example.jatin.myapplication2"
     pkg: /data/local/tmp/com.example.jatin.myapplication2
Success


$ adb shell am start -n     "com.example.jatin.myapplication2/com.example.jatin.AgentSpy.MainActivity" -a    android.intent.action.MAIN -c android.intent.category.LAUNCHER
Client not ready yet..Waiting for process to come online
Connected to process 7445 on device xiaomi-mi_4i-a67ae459
D/###BVRREC###: true
I/MediaRecorderJNI: prepare: surface=0x5583ad0d30
I/Choreographer: Skipped 64 frames!  The application may be doing too much     work on its main thread.
D/###BVRREC###: false
V/RenderScript: Application requested CPU execution
V/RenderScript: 0x558342fa80 Launching thread(s), CPUs 8
D/###BVRREC###: true
I/MediaRecorderJNI: prepare: surface=0x5583b23330
I/Choreographer: Skipped 42 frames!  The application may be doing too much     work               on its main thread.
     D/###BVRREC###: false
    Application terminated.
4

2 回答 2

0

请参阅BroadcastReceiver,您不能HandlerThread在方法中使用onReceive

接收器生命周期

任何需要异步操作的东西都不可用,因为您需要从函数返回来处理异步操作,但此时 BroadcastReceiver 不再处于活动状态,因此系统可以在异步操作完成之前自由地终止其进程。

流程生命周期

...... 这意味着,对于运行时间较长的操作,您经常将 Service与 BroadcastReceiver 结合使用,以在整个操作期间保持包含进程的活动状态。

所以请遵循 ANDROID API 指南:要在调用时运行较长时间的操作onReceive,您应该启动一个服务,然后在服务中创建另一个线程。

有关创建一个并在收到消息时仅休眠 5 秒的示例代码,请参阅扩展服务类。HandlerThread

于 2016-08-09T07:08:24.440 回答
0

您可以使用 goAsync() 方法。 https://developer.android.com/reference/android/content/BroadcastReceiver.html#

于 2016-08-06T23:20:06.087 回答