如何在不同的线程中运行绑定的服务

时间:2019-04-10 02:34:00

标签: android

我的应用程序使用相机,它显示相机预览,并在每个预览帧上将帧数据编码为base64格式,以调用我的远程Web服务。

由于产生帧的速度与消耗帧(调用Web服务)的速度不匹配,因此我考虑在服务中使用缓冲区(消息队列),因此我使用Messenger来绑定服务。

因此,我考虑使用该服务,并将其绑定到我的CameraActivity。默认情况下,服务在与UI线程相同的线程中运行,但是,我想在另一个线程中运行服务。我已经读过ServiceBound service,他们只是提到我可以在其他线程中运行该服务,但没有给出示例。

CameraActivity

public class CameraActivity extends AppCompatActivity implements Camera.PreviewCallback {
    private Camera camera;
    private CameraPreview preview;
    int cnt = 0, RATE = 0;
    private Messenger messenger;//use to communicate with CloudService
    private boolean bound = false;

    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            messenger = new Messenger(service);
            bound = true;
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            messenger = null;
            bound = false;
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera);
        camera = getCamera();
        RATE = camera.getParameters().getPreviewFrameRate() / 5;
        preview = new CameraPreview(this, camera);
        FrameLayout layout = findViewById(R.id.camera_preview);
        layout.addView(preview);

        bindService(new Intent(this, CloudService.class), connection,
                Context.BIND_AUTO_CREATE);

    }

    public static Camera getCamera() {
        Camera camera = null;
        try {
            camera = Camera.open();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return camera;
    }

    @Override
    public void onPreviewFrame(byte[] data, Camera camera) {
        if (cnt == RATE) {
            if (bound) {
                Message message = Message.obtain(null, 0, data);
                try {
                    messenger.send(message);
                    Log.d("activity", "send msg");
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
            cnt = 0;
        }
        cnt++;
    }

    protected void onStop() {
        super.onStop();
        if (bound){
            unbindService(connection);
            bound = false;
        }
    }
}

CloudService

    private Thread thread;
    private Messenger messenger;

    public CloudService() {
        Log.d("cloud service", "create");
        thread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    Log.d("cloud service", "thread running");
                }

            }
        });
    }

    @Override
    public IBinder onBind(Intent intent) {
        messenger = new Messenger(new PreviewHandler(this));
        return messenger.getBinder();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d("cloud service", "start");
        thread.start();
        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        thread.interrupt();
        Log.d("cloud service", "destroy");
    }

    static class PreviewHandler extends Handler {
        private CloudService service;

        public PreviewHandler(CloudService service) {
            this.service = service;
        }

        @Override
        public void handleMessage(Message message) {
            byte[] data = (byte[]) message.obj;
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Log.d("message", "msg!!!");
        }
    }

}

如何在CloudService中正确使用线程?

1 个答案:

答案 0 :(得分:0)

解决方案:一起使用HandlerThreadHandler完成任务。

public class CloudService extends Service {
    private static final String TAG = "CloudService";

    private HandlerThread handlerThread;
    private PreviewHandler handler;
    private Messenger messenger;

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "onCreate");

        handlerThread = new HandlerThread("CloudService_HandlerThread");
        handlerThread.start();
        handler = new PreviewHandler(handlerThread.getLooper());
    }

    @Override
    public IBinder onBind(Intent intent) {
        Log.d(TAG, "onBind");

        messenger = new Messenger(handler);
        return messenger.getBinder();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "onStartCommand");
        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        Log.d(TAG, "onDestroy");
        handlerThread.quit();
    }

    static class PreviewHandler extends Handler {
        PreviewHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message message) {
            byte[] data = (byte[]) message.obj;
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Log.d(TAG, "handleMessage from thread " + Thread.currentThread().getName());
        }
    }
}