0

In the case of operating Service in a process different from Activity by using "android:proces", I confirmed that Looper and MainThread also exists in the process where Service exists. Who generated Main Thread and Looper running in the process where Service exists?

I confirmed that the lifecycle method in Service is called by ActivityThread, and there is only one Looper and MainThread when Activity and Service are operating in the same process.


■MainActivity.java

public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    Intent intent = null;
    Button btn = null;
    boolean mode = false;
    static final String TAG = "servicedebug";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btn = (Button)findViewById(R.id.service_btn);
        btn.setOnClickListener(this);

        Log.i(TAG, "MainActivity#onCreate(): getMainLooper().toString()"
                + getMainLooper().toString());

        intent = new Intent(this, TestService.class);
    }

    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        if (v.getId() == R.id.service_btn) {
            if (!mode) {
                startService(intent);
                btn.setText("stop");
                mode = true;
            }
            else {
                stopService(intent);
                btn.setText("start");
                mode = false;
            }
        }
    }

}

■TestService.java

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

    int resTrace = getTrace("TestService#init");

    public TestService(){
        Log.i(TAG, "TestService#TestService()");
    }

    public int getTrace(String s){
        StackTraceElement[] ste = new Throwable().getStackTrace();
        for(int i = 0; i < ste.length; i++){
            Log.i(TAG, s + " ste[" + i + "] = " + ste[i]);
        }
        return 1;
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // TODO Auto-generated method stub
        super.onStart(intent, startId);
        Log.i(TAG, "TestService#onStartCommand(): getMainLooper().toString()"
                + getMainLooper().toString());
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onCreate() {
        Thread.currentThread().setName("Mythread-XXXX");

        Log.i(TAG, "TestService#onCreate getMainLooper().toString()"
                + getMainLooper().toString());
        getTrace("TestService#onCreate");
    }

    @Override
    public void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
    }
}

The log when executing the above test code is as follows.

■In the case of using

Looper and MainThread were different for each process.

03-31 05:02:30.919 872-872/com.example.a172000016.service_processtest01 I/servicedebug: MainActivity#onCreate(): getMainLooper().toString()Looper (main, tid 1) {5450d66}
03-31 /? I/servicedebug: TestService#init ste[0] = com.example.a172000016.service_processtest01.TestService.getTrace(TestService.java:19)
03-31 /? I/servicedebug: TestService#init ste[1] = com.example.a172000016.service_processtest01.TestService.<init>(TestService.java:12)
03-31 /? I/servicedebug: TestService#init ste[2] = java.lang.Class.newInstance(Native Method)
03-31 /? I/servicedebug: TestService#init ste[3] = android.app.ActivityThread.handleCreateService(ActivityThread.java:3173)
03-31 /? I/servicedebug: TestService#init ste[4] = android.app.ActivityThread.-wrap5(ActivityThread.java)
03-31 /? I/servicedebug: TestService#init ste[5] = android.app.ActivityThread$H.handleMessage(ActivityThread.java:1567)
03-31 /? I/servicedebug: TestService#init ste[6] = android.os.Handler.dispatchMessage(Handler.java:102)
03-31 /? I/servicedebug: TestService#init ste[7] = android.os.Looper.loop(Looper.java:154)
03-31 /? I/servicedebug: TestService#init ste[8] = android.app.ActivityThread.main(ActivityThread.java:6119)
03-31 /? I/servicedebug: TestService#init ste[9] = java.lang.reflect.Method.invoke(Native Method)
03-31 /? I/servicedebug: TestService#init ste[10] = com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
03-31 /? I/servicedebug: TestService#init ste[11] = com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
03-31 /? I/servicedebug: TestService#TestService()
03-31 /? I/servicedebug: TestService#onCreate getMainLooper().toString()Looper (Mythread-XXXX, tid 1) {e3893a9}
03-31 /? I/servicedebug: TestService#onCreate ste[0] = com.example.a172000016.service_processtest01.TestService.getTrace(TestService.java:19)
03-31 /? I/servicedebug: TestService#onCreate ste[1] = com.example.a172000016.service_processtest01.TestService.onCreate(TestService.java:47)
03-31 /? I/servicedebug: TestService#onCreate ste[2] = android.app.ActivityThread.handleCreateService(ActivityThread.java:3191)
03-31 /? I/servicedebug: TestService#onCreate ste[3] = android.app.ActivityThread.-wrap5(ActivityThread.java)
03-31 /? I/servicedebug: TestService#onCreate ste[4] = android.app.ActivityThread$H.handleMessage(ActivityThread.java:1567)
03-31 /? I/servicedebug: TestService#onCreate ste[5] = android.os.Handler.dispatchMessage(Handler.java:102)
03-31 /? I/servicedebug: TestService#onCreate ste[6] = android.os.Looper.loop(Looper.java:154)
03-31 /? I/servicedebug: TestService#onCreate ste[7] = android.app.ActivityThread.main(ActivityThread.java:6119)
03-31 /? I/servicedebug: TestService#onCreate ste[8] = java.lang.reflect.Method.invoke(Native Method)
03-31 /? I/servicedebug: TestService#onCreate ste[9] = com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
03-31 /? I/servicedebug: TestService#onCreate ste[10] = com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
03-31 /? I/servicedebug: TestService#onStartCommand(): getMainLooper().toString()Looper (Mythread-XXXX, tid 1) {e3893a9}

■In the case of using

Looper and MainThread were same in a process.

03-31 05:09:13.207 6688-6688/com.example.a172000016.service_processtest01 I/servicedebug: MainActivity#onCreate(): getMainLooper().toString()Looper (main, tid 1) {5450d66}
03-31    I/servicedebug: TestService#init ste[0] = com.example.a172000016.service_processtest01.TestService.getTrace(TestService.java:19)
03-31    I/servicedebug: TestService#init ste[1] = com.example.a172000016.service_processtest01.TestService.<init>(TestService.java:12)
03-31    I/servicedebug: TestService#init ste[2] = java.lang.Class.newInstance(Native Method)
03-31    I/servicedebug: TestService#init ste[3] = android.app.ActivityThread.handleCreateService(ActivityThread.java:3173)
03-31    I/servicedebug: TestService#init ste[4] = android.app.ActivityThread.-wrap5(ActivityThread.java)
03-31    I/servicedebug: TestService#init ste[5] = android.app.ActivityThread$H.handleMessage(ActivityThread.java:1567)
03-31    I/servicedebug: TestService#init ste[6] = android.os.Handler.dispatchMessage(Handler.java:102)
03-31    I/servicedebug: TestService#init ste[7] = android.os.Looper.loop(Looper.java:154)
03-31    I/servicedebug: TestService#init ste[8] = android.app.ActivityThread.main(ActivityThread.java:6119)
03-31    I/servicedebug: TestService#init ste[9] = java.lang.reflect.Method.invoke(Native Method)
03-31    I/servicedebug: TestService#init ste[10] = com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
03-31    I/servicedebug: TestService#init ste[11] = com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
03-31    I/servicedebug: TestService#TestService()
03-31    I/servicedebug: TestService#onCreate getMainLooper().toString()Looper (Mythread-XXXX, tid 1) {5450d66}
03-31    I/servicedebug: TestService#onCreate ste[0] = com.example.a172000016.service_processtest01.TestService.getTrace(TestService.java:19)
03-31    I/servicedebug: TestService#onCreate ste[1] = com.example.a172000016.service_processtest01.TestService.onCreate(TestService.java:47)
03-31    I/servicedebug: TestService#onCreate ste[2] = android.app.ActivityThread.handleCreateService(ActivityThread.java:3191)
03-31    I/servicedebug: TestService#onCreate ste[3] = android.app.ActivityThread.-wrap5(ActivityThread.java)
03-31    I/servicedebug: TestService#onCreate ste[4] = android.app.ActivityThread$H.handleMessage(ActivityThread.java:1567)
03-31    I/servicedebug: TestService#onCreate ste[5] = android.os.Handler.dispatchMessage(Handler.java:102)
03-31    I/servicedebug: TestService#onCreate ste[6] = android.os.Looper.loop(Looper.java:154)
03-31    I/servicedebug: TestService#onCreate ste[7] = android.app.ActivityThread.main(ActivityThread.java:6119)
03-31    I/servicedebug: TestService#onCreate ste[8] = java.lang.reflect.Method.invoke(Native Method)
03-31    I/servicedebug: TestService#onCreate ste[9] = com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
03-31    I/servicedebug: TestService#onCreate ste[10] = com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
03-31    I/servicedebug: TestService#onStartCommand(): getMainLooper().toString()Looper (Mythread-XXXX, tid 1) {5450d66}
  • Not sure what you do differently in the two tests, but from the documentation on services: A service runs in the main thread of its hosting process; the service does not create its own thread and does not run in a separate process https://developer.android.com/guide/components/services.html – cYrixmorten Apr 09 '18 at 14:45
  • thank you for your reply. A service runs in the main thread of its hosting process; the service does not create its own thread and does not run in a separate process unless you specify otherwise – kuraba-saver Apr 09 '18 at 15:09
  • thank you for your reply. "not run in a separate process unless you specify otherwise" that means , By using android:process , service runs in a separate process. I understand it. The point I do not know is when the service runs in a separate process, which source code Loooper in this process was generated. I searched for "Looper.prepare", but I can not find the place where process is separated. – kuraba-saver Apr 09 '18 at 15:24
  • (A)Looper and MainThread were different for each process. Activity : Looper (main, tid 1) {5450d66} Service : Looper (Mythread-XXXX, tid 1) {e3893a9} (B)Looper and MainThread were same in a process. Activity : Looper (main, tid 1) {5450d66} Service : Looper (Mythread-XXXX, tid 1) {5450d66} – kuraba-saver Apr 09 '18 at 15:32
  • Must admit that it is outside the scope of my knowledge :) though it must be possible to dig up the magic around android:process in the documentation or source code. Not sure what you wish to archive by this. Is it simply to understand the concept? Cause if it is to lift heavy work I would personally prefer spawning a background thread in the service. Perhaps paired with making it a Foreground Service. – cYrixmorten Apr 09 '18 at 15:51

0 Answers0