-1

Is it possible to use HandlerThread inside BroadcastReceiver's onReceive method which further starts a service on the main UI thread??

My aim is to use HandlerThread inside onReceive method ,so that the service gets started in the separate thread.

But don't know how to implement it.

Any hints ?

Thanks

EDIT : Service class

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) {
}


}

I think I am not using services correctly . Please help.

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.
  • Why do you want to call `startService()` in a separate thread? Explain please. – David Wasser Aug 08 '16 at 11:25
  • Because each time I am running the application , there's a message in my log cat ."Too much wokring on the main thread" and my device slows down. – Jatin Khattar Aug 08 '16 at 11:37
  • You won't fix that by calling `startService()` in another thread. Your problem is somewhere else. Post the code of your `onStart()` or `onStartCommand()` method. – David Wasser Aug 08 '16 at 11:41
  • I am recording video without preview from my service but it shows " ** The application may be doing too much work on its main thread** . " and i didnt use _onStartCommand()_ or _onStart()_ – Jatin Khattar Aug 08 '16 at 12:25
  • All lifecycle methods (`onCreate()`, `onStart()`, `onStartCommand()`, etc.) are called on the main thread. These methods all need to return rather quickly. Any background processing needs to be done in background threads which you will need to start yourself. It is also possible that you are doing too much work on the main thread in an `Activity`. You'll need to post more code for us to help you. – David Wasser Aug 09 '16 at 08:52
  • I am not using any activity . There are 2 classes 1.) `BroadcastReceiver` and 2.) A `Service` – Jatin Khattar Aug 09 '16 at 20:20
  • Then post the code from your `Service` – David Wasser Aug 10 '16 at 07:25
  • @DavidWasser , I have posted my `service` class. Please have a look and point out where I am doing it in a wrong way.Because this code is not working on micromax and other non MI devices. App crashes on using this service. Thanks – Jatin Khattar Aug 10 '16 at 09:54
  • According to the [documentation](https://developer.android.com/guide/topics/media/camera.html#capture-video), the calls to `MediaRecorder` to capture video must be made in a very specific order. Your call to `setPreviewDisplay()` is made too early in the call sequence, and you are doing this differently from the way it is described in the documentation. I do not have any experience with video recording, so I'm just trying to help here. I would suggest that you try it exactly the way the documentation indicates, and see if that helps you. – David Wasser Aug 10 '16 at 18:34
  • Also, if you have crashes, please post the relevant logs and stack trace from logcat. – David Wasser Aug 10 '16 at 18:36
  • haah ! Bugs Fixed on non samsung devices and @DavidWasser , I have reordered `setPreviewDisplay()` but still it says- : `The application may be doing too much work on its main Thread ` – Jatin Khattar Aug 11 '16 at 12:48
  • Maybe you need to create the `SurfaceView` in a background thread. You could try that and see if the behaviour is different. – David Wasser Aug 11 '16 at 14:26

2 Answers2

0

You can use goAsync() method. https://developer.android.com/reference/android/content/BroadcastReceiver.html#

Chait
  • 537
  • 6
  • 15
0

Refer to BroadcastReceiver, you can NOT use HandlerThread in onReceive method:

Receiver Lifecycle

anything that requires asynchronous operation is not available, because you will need to return from the function to handle the asynchronous operation, but at that point the BroadcastReceiver is no longer active and thus the system is free to kill its process before the asynchronous operation completes.

Process Lifecycle

...... This means that for longer-running operations you will often use a Service in conjunction with a BroadcastReceiver to keep the containing process active for the entire time of your operation.

SO PLEASE FOLLOW ANDROID API GUIDES: To run a longer-running operation when onReceive invoked, you should start a service, then create another thread in service.

Refer to Extending the Service class for sample code which create a HandlerThread and just sleep for 5 seconds when message received.

Weiyi
  • 1,843
  • 2
  • 22
  • 34
  • Then any suggestion how to perform long running operation inside on Receive except service as I am using Service still not getting desired results – Jatin Khattar Aug 09 '16 at 20:17
  • If perform long running operation is your purpose, why service cannot meet your desired? How do you implement it? – Weiyi Aug 10 '16 at 02:21
  • Exatly.There you are . I am searching solution to this problem , why it shows `The Application may perform too much work on its main thread` though my app is working fine ,but my device slows down – Jatin Khattar Aug 10 '16 at 04:32
  • It is important to clarify that: the service is running in the UI thread. And you have to create and start another thread in the service. – Weiyi Aug 10 '16 at 05:36
  • refer to the end of my answer. you can get sample code from Android Doc. – Weiyi Aug 11 '16 at 17:18
  • Keep in mind that that using a background service is not doable as of Android Oreo. You can use a `JobIntentService`, though it may be delayed. – lionscribe Oct 15 '20 at 15:33