欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

(六十九) 探究如何让Service anr?

程序员文章站 2022-07-15 12:06:23
...

demo地址:https://github.com/happyjiatai/demo_csdn/tree/master/demo_69_service

参考:

1.(六十五)Android O StartService的 anr timeout 流程分析

2. (七十)Android O Service启动流程梳理——bindService

3. (六十四)Android O Service启动流程梳理——startService

4. Android中bindService的细节之二:从进程的角度分析绑定Service的流程【Service所在进程已存在】

 

1.起因

最近在看Service的启动源码,涉及anr这块,发生anr是统计了特定方法执行时间,如果超过限定值,则anr,和我之前想的不大一样。简单地让Service anr的做法是在onCreate或者onStartCommand或者onBind或者onUnbind或者onDestroy中执行20s+的操作,则anr,不需要几者累加大于20s,统计是分开统计的,和几者耗时之和没有关系,以上耗时之和可以大于20s。(后台Service是200s)

 

2.测试demo

写了个demo:

布局:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/buttonStart"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:text="startService"
        app:layout_constraintBottom_toTopOf="@+id/buttonBind"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.219" />

    <Button
        android:id="@+id/buttonBind"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="268dp"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        android:text="bindService"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />
</android.support.constraint.ConstraintLayout>

string

<resources>
    <string name="app_name">Demo_69_service</string>
    <string name="channel_name">channel_name</string>
    <string name="channel_description">channel_description</string>
</resources>

 

AndroidManifest

 

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.demo_69_service">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service
            android:name=".MyService"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.csdnservice" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </service>
    </application>

</manifest>

Activity

package com.example.demo_69_service;

import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "demo69_activity";
    private MyService myService;
    private boolean isBound = false;

    private ServiceConnection conn = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d(TAG, "onServiceConnected", new RuntimeException());
            isBound = true;
            MyService.MyBinder binder = (MyService.MyBinder) service;
            myService = binder.getService();
        }

        //client 和service连接意外丢失时,会调用该方法
        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d(TAG, "onServiceDisconnected", new RuntimeException());
        }

    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final Intent serviceIntent = new Intent("android.intent.action.csdnservice");
        serviceIntent.setPackage("com.example.demo_69_service");
        Button btnForStartService = findViewById(R.id.buttonStart);
        btnForStartService.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startForegroundService(serviceIntent);
            }
        });
        Button btnForBindService = findViewById(R.id.buttonBind);
        btnForBindService.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                bindService(serviceIntent, conn, BIND_AUTO_CREATE);
            }
        });
    }


}

Service:

package com.example.demo_69_service;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;

public class MyService extends Service {
    private static final String TAG = "demo69_service";
    private MyBinder Ibind = new MyBinder();

    public class MyBinder extends Binder {

        public MyService getService() {
            return MyService.this;
        }
    }

    public MyService() {
    }

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

    }

    @Override
    public IBinder onBind(Intent intent) {
        Log.d(TAG, "onBind", new RuntimeException());
        return Ibind;
    }

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

    private void createNotificationChannel() {
        NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        // 通知渠道的id
        String id = "my_channel_01";
        // 用户可以看到的通知渠道的名字.
        CharSequence name = getString(R.string.channel_name);
//         用户可以看到的通知渠道的描述
        String description = getString(R.string.channel_description);
        int importance = NotificationManager.IMPORTANCE_HIGH;
        NotificationChannel mChannel = new NotificationChannel(id, name, importance);
//         配置通知渠道的属性
        mChannel.setDescription(description);
//         设置通知出现时的闪灯(如果 android 设备支持的话)
        mChannel.enableLights(true); mChannel.setLightColor(Color.RED);
//         设置通知出现时的震动(如果 android 设备支持的话)
        mChannel.enableVibration(true);
        mChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
//         最后在notificationmanager中创建该通知渠道 //
        mNotificationManager.createNotificationChannel(mChannel);

        // 为该通知设置一个id
        int notifyID = 1;
        // 通知渠道的id
        String CHANNEL_ID = "my_channel_01";
        // Create a notification and set the notification channel.
        Notification notification = new Notification.Builder(this)
                .setContentTitle("New Message") .setContentText("You've received new messages.")
                .setSmallIcon(R.drawable.ic_launcher_foreground)
                .setChannelId(CHANNEL_ID)
                .build();
        startForeground(1,notification);
    }
}

 

3.测试

3.1 startService

 

07-13 23:51:43.602 6525-6525/com.example.demo_69_service D/demo69_service: onCreate
    java.lang.RuntimeException
        at com.example.demo_69_service.MyService.onCreate(MyService.java:31)
        at android.app.ActivityThread.handleCreateService(ActivityThread.java:3442)
        at android.app.ActivityThread.-wrap4(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1711)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:171)
        at android.app.ActivityThread.main(ActivityThread.java:6684)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:246)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:783)
07-13 23:51:43.616 6525-6525/com.example.demo_69_service D/demo69_service: onStartCommand
    java.lang.RuntimeException
        at com.example.demo_69_service.MyService.onStartCommand(MyService.java:44)
        at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3577)
        at android.app.ActivityThread.-wrap20(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1726)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:171)
        at android.app.ActivityThread.main(ActivityThread.java:6684)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:246)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:783)

 

3.2 bindService

 

07-14 13:08:12.852 3992-3992/com.example.demo_69_service D/demo69_service: onCreate
    java.lang.RuntimeException
        at com.example.demo_69_service.MyService.onCreate(MyService.java:31)
        at android.app.ActivityThread.handleCreateService(ActivityThread.java:3442)
        at android.app.ActivityThread.-wrap4(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1711)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:171)
        at android.app.ActivityThread.main(ActivityThread.java:6684)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:246)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:783)
07-14 13:08:12.856 3992-3992/com.example.demo_69_service D/demo69_service: onBind
    java.lang.RuntimeException
        at com.example.demo_69_service.MyService.onBind(MyService.java:38)
        at android.app.ActivityThread.handleBindService(ActivityThread.java:3469)
        at android.app.ActivityThread.-wrap2(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1716)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:171)
        at android.app.ActivityThread.main(ActivityThread.java:6684)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:246)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:783)
07-14 13:08:12.857 3992-3992/com.example.demo_69_service D/demo69_activity: onServiceConnected
    java.lang.RuntimeException
        at com.example.demo_69_service.MainActivity$1.onServiceConnected(MainActivity.java:22)
        at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1645)
        at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1674)
        at android.os.Handler.handleCallback(Handler.java:789)
        at android.os.Handler.dispatchMessage(Handler.java:98)
        at android.os.Looper.loop(Looper.java:171)
        at android.app.ActivityThread.main(ActivityThread.java:6684)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:246)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:783)

小米mix只走了了onCreate和onBind方法,onStartCommand是不走的。

 

3.3 startService+bindService

第一次start Service

07-13 23:51:43.602 6525-6525/com.example.demo_69_service D/demo69_service: onCreate
    java.lang.RuntimeException
        at com.example.demo_69_service.MyService.onCreate(MyService.java:31)
        at android.app.ActivityThread.handleCreateService(ActivityThread.java:3442)
        at android.app.ActivityThread.-wrap4(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1711)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:171)
        at android.app.ActivityThread.main(ActivityThread.java:6684)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:246)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:783)
07-13 23:51:43.616 6525-6525/com.example.demo_69_service D/demo69_service: onStartCommand
    java.lang.RuntimeException
        at com.example.demo_69_service.MyService.onStartCommand(MyService.java:44)
        at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3577)
        at android.app.ActivityThread.-wrap20(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1726)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:171)
        at android.app.ActivityThread.main(ActivityThread.java:6684)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:246)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:783)

 

第一次启动bind Service

 

07-13 23:52:18.474 6525-6525/com.example.demo_69_service D/demo69_service: onBind
    java.lang.RuntimeException
        at com.example.demo_69_service.MyService.onBind(MyService.java:38)
        at android.app.ActivityThread.handleBindService(ActivityThread.java:3469)
        at android.app.ActivityThread.-wrap2(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1716)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:171)
        at android.app.ActivityThread.main(ActivityThread.java:6684)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:246)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:783)
07-13 23:52:18.483 6525-6525/com.example.demo_69_service D/demo69_activity: onServiceConnected
    java.lang.RuntimeException
        at com.example.demo_69_service.MainActivity$1.onServiceConnected(MainActivity.java:22)
        at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1645)
        at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1674)
        at android.os.Handler.handleCallback(Handler.java:789)
        at android.os.Handler.dispatchMessage(Handler.java:98)
        at android.os.Looper.loop(Looper.java:171)
        at android.app.ActivityThread.main(ActivityThread.java:6684)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:246)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:783)

 

第二次start Service

07-13 23:58:09.283 6525-6525/com.example.demo_69_service D/demo69_service: onStartCommand
    java.lang.RuntimeException
        at com.example.demo_69_service.MyService.onStartCommand(MyService.java:44)
        at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3577)
        at android.app.ActivityThread.-wrap20(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1726)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:171)
        at android.app.ActivityThread.main(ActivityThread.java:6684)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:246)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:783)

 

第二次启动bind Service

尴尬,一个log都没有

小米 mix2是不会重复bind的。这里对应原因:

ActiveServices.java

    private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,
            boolean execInFg, boolean rebind) throws TransactionTooLargeException {
        if (r.app == null || r.app.thread == null) {
            // If service is not currently running, can't yet bind.
            return false;
        }
        if (DEBUG_SERVICE) Slog.d(TAG_SERVICE, "requestBind " + i + ": requested=" + i.requested
                + " rebind=" + rebind);
        if ((!i.requested || rebind) && i.apps.size() > 0) {
            try {
                bumpServiceExecutingLocked(r, execInFg, "bind");
                r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
                r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
                        r.app.repProcState);
                if (!rebind) {
                    i.requested = true;
                }
                i.hasBound = true;
                i.doRebind = false;
            } catch (TransactionTooLargeException e) {
                // Keep the executeNesting count accurate.
                if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Crashed while binding " + r, e);
                final boolean inDestroying = mDestroyingServices.contains(r);
                serviceDoneExecutingLocked(r, inDestroying, inDestroying);
                throw e;
            } catch (RemoteException e) {
                if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Crashed while binding " + r);
                // Keep the executeNesting count accurate.
                final boolean inDestroying = mDestroyingServices.contains(r);
                serviceDoneExecutingLocked(r, inDestroying, inDestroying);
                return false;
            }
        }
        return true;
    }i.requested || rebind) && i.apps.size() > 0) {
            try {
                bumpServiceExecutingLocked(r, execInFg, "bind");
                r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
                r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
                        r.app.repProcState);
                if (!rebind) {
                    i.requested = true;
                }
                i.hasBound = true;
                i.doRebind = false;
            } catch (TransactionTooLargeException e) {
                // Keep the executeNesting count accurate.
                if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Crashed while binding " + r, e);
                final boolean inDestroying = mDestroyingServices.contains(r);
                serviceDoneExecutingLocked(r, inDestroying, inDestroying);
                throw e;
            } catch (RemoteException e) {
                if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Crashed while binding " + r);
                // Keep the executeNesting count accurate.
                final boolean inDestroying = mDestroyingServices.contains(r);
                serviceDoneExecutingLocked(r, inDestroying, inDestroying);
                return false;
            }
        }
        return true;
    }

bind过之后b.requested为true就不会再走进去了(IntentBindRecord),rebind传进来的时候就是false。

                    b.binder = service;
                    b.requested = true;
                    b.received = true;

而connect方法是否会重复调用取决于LoadedApk

                old = mActiveConnections.get(name);
                if (old != null && old.binder == service) {
                    // Huh, already have this one.  Oh well!
                    return;
                }

 

 

3.4 second activity bind

修改多启动一个activity然后bind到该Service

log:

07-14 15:19:37.718 10747-10747/com.example.demo_69_service D/demo69_activity: bindService success :
07-14 15:19:37.756 10747-10747/com.example.demo_69_service D/demo69_service: onCreate
    java.lang.RuntimeException
        at com.example.demo_69_service.MyService.onCreate(MyService.java:31)
        at android.app.ActivityThread.handleCreateService(ActivityThread.java:3442)
        at android.app.ActivityThread.-wrap4(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1711)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:171)
        at android.app.ActivityThread.main(ActivityThread.java:6684)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:246)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:783)
07-14 15:19:37.771 10747-10747/com.example.demo_69_service D/demo69_service: onBind
    java.lang.RuntimeException
        at com.example.demo_69_service.MyService.onBind(MyService.java:38)
        at android.app.ActivityThread.handleBindService(ActivityThread.java:3469)
        at android.app.ActivityThread.-wrap2(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1716)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:171)
        at android.app.ActivityThread.main(ActivityThread.java:6684)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:246)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:783)
07-14 15:19:37.778 10747-10747/com.example.demo_69_service D/demo69_activity: onServiceConnected
    java.lang.RuntimeException
        at com.example.demo_69_service.MainActivity$1.onServiceConnected(MainActivity.java:22)
        at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1645)
        at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1674)
        at android.os.Handler.handleCallback(Handler.java:789)
        at android.os.Handler.dispatchMessage(Handler.java:98)
        at android.os.Looper.loop(Looper.java:171)
        at android.app.ActivityThread.main(ActivityThread.java:6684)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:246)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:783)
07-14 15:19:42.779 10747-10747/com.example.demo_69_service D/demo69_activity: onServiceConnected 5s later



07-14 15:19:54.264 10747-10747/com.example.demo_69_service D/demo69_activity2: oncreate:
07-14 15:19:58.237 10747-10747/com.example.demo_69_service D/demo69_activity2: bindService success :
07-14 15:19:58.243 10747-10747/com.example.demo_69_service D/demo69_activity2: onServiceConnected
    java.lang.RuntimeException
        at com.example.demo_69_service.Main2Activity$1.onServiceConnected(Main2Activity.java:22)
        at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1645)
        at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1674)
        at android.os.Handler.handleCallback(Handler.java:789)
        at android.os.Handler.dispatchMessage(Handler.java:98)
        at android.os.Looper.loop(Looper.java:171)
        at android.app.ActivityThread.main(ActivityThread.java:6684)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:246)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:783)
07-14 15:20:03.245 10747-10747/com.example.demo_69_service D/demo69_activity2: onServiceConnected 5s later

从log来看onBind不会被调用第二次,不管是一个activity还是第二个activity。

这个还有结合源码再看一下原因,待续。第四篇参考博客是这么说的

(六十九) 探究如何让Service anr?

对应代码在ActiveServices.java内

            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Bind " + s + " with " + b
                    + ": received=" + b.intent.received
                    + " apps=" + b.intent.apps.size()
                    + " doRebind=" + b.intent.doRebind);

            if (s.app != null && b.intent.received) {
                // Service is already running, so we can immediately
                // publish the connection.
                try {
                    c.conn.connected(s.name, b.intent.binder, false);
                } catch (Exception e) {
                    Slog.w(TAG, "Failure sending service " + s.shortName
                            + " to connection " + c.conn.asBinder()
                            + " (in " + c.binding.client.processName + ")", e);
                }

                // If this is the first app connected back to this binding,
                // and the service had previously asked to be told when
                // rebound, then do so.
                if (b.intent.apps.size() == 1 && b.intent.doRebind) {
                    requestServiceBindingLocked(s, b.intent, callerFg, true);
                }
            } else if (!b.intent.requested) {
                requestServiceBindingLocked(s, b.intent, callerFg, false);
            }b.intent.received) {
                // Service is already running, so we can immediately
                // publish the connection.
                try {
                    c.conn.connected(s.name, b.intent.binder, false);
                } catch (Exception e) {
                    Slog.w(TAG, "Failure sending service " + s.shortName
                            + " to connection " + c.conn.asBinder()
                            + " (in " + c.binding.client.processName + ")", e);
                }

                // If this is the first app connected back to this binding,
                // and the service had previously asked to be told when
                // rebound, then do so.
                if (b.intent.apps.size() == 1 && b.intent.doRebind) {
                    requestServiceBindingLocked(s, b.intent, callerFg, true);
                }
            } else if (!b.intent.requested) {
                requestServiceBindingLocked(s, b.intent, callerFg, false);
            }

 

3.5 多个持续不断的start service

添加一个按钮,startMore

        Button btnForStartMore = findViewById(R.id.buttonStartMore);
        btnForStartMore.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                for(int i = 0; i< 5; i++) {
                    Log.d(TAG, "btnForStartMore :" + i);
                    startService(serviceIntent);
                }
            }
        });

service的onStartCommand睡眠以模拟耗时操作

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "onStartCommand: " + startId, new RuntimeException());
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return super.onStartCommand(intent, flags, startId);
    }


效果:

 

(六十九) 探究如何让Service anr?

 

log:

07-14 14:37:04.250 7526-7526/com.example.demo_69_service D/demo69_service: onCreate
    java.lang.RuntimeException
        at com.example.demo_69_service.MyService.onCreate(MyService.java:31)
        at android.app.ActivityThread.handleCreateService(ActivityThread.java:3442)
        at android.app.ActivityThread.-wrap4(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1711)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:171)
        at android.app.ActivityThread.main(ActivityThread.java:6684)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:246)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:783)
07-14 14:37:04.263 7526-7526/com.example.demo_69_service D/demo69_service: onStartCommand: 1
    java.lang.RuntimeException
        at com.example.demo_69_service.MyService.onStartCommand(MyService.java:50)
        at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3577)
        at android.app.ActivityThread.-wrap20(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1726)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:171)
        at android.app.ActivityThread.main(ActivityThread.java:6684)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:246)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:783)
07-14 14:37:09.323 7526-7526/com.example.demo_69_service D/demo69_activity: btnForStartMore :0
07-14 14:37:09.335 7526-7526/com.example.demo_69_service D/demo69_activity: btnForStartMore :1
07-14 14:37:09.344 7526-7526/com.example.demo_69_service D/demo69_activity: btnForStartMore :2
07-14 14:37:09.352 7526-7526/com.example.demo_69_service D/demo69_activity: btnForStartMore :3
07-14 14:37:09.361 7526-7526/com.example.demo_69_service D/demo69_activity: btnForStartMore :4
07-14 14:37:09.384 7526-7526/com.example.demo_69_service D/demo69_service: onStartCommand: 2
    java.lang.RuntimeException
        at com.example.demo_69_service.MyService.onStartCommand(MyService.java:50)
        at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3577)
        at android.app.ActivityThread.-wrap20(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1726)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:171)
        at android.app.ActivityThread.main(ActivityThread.java:6684)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:246)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:783)
07-14 14:37:14.396 7526-7526/com.example.demo_69_service D/demo69_service: onStartCommand: 3
    java.lang.RuntimeException
        at com.example.demo_69_service.MyService.onStartCommand(MyService.java:50)
        at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3577)
        at android.app.ActivityThread.-wrap20(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1726)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:171)
        at android.app.ActivityThread.main(ActivityThread.java:6684)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:246)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:783)
07-14 14:37:19.411 7526-7526/com.example.demo_69_service D/demo69_service: onStartCommand: 4
    java.lang.RuntimeException
        at com.example.demo_69_service.MyService.onStartCommand(MyService.java:50)
        at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3577)
        at android.app.ActivityThread.-wrap20(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1726)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:171)
        at android.app.ActivityThread.main(ActivityThread.java:6684)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:246)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:783)
07-14 14:37:24.424 7526-7526/com.example.demo_69_service D/demo69_service: onStartCommand: 5
    java.lang.RuntimeException
        at com.example.demo_69_service.MyService.onStartCommand(MyService.java:50)
        at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3577)
        at android.app.ActivityThread.-wrap20(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1726)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:171)
        at android.app.ActivityThread.main(ActivityThread.java:6684)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:246)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:783)
07-14 14:37:29.430 7526-7526/com.example.demo_69_service D/demo69_service: onStartCommand: 6
    java.lang.RuntimeException
        at com.example.demo_69_service.MyService.onStartCommand(MyService.java:50)
        at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3577)
        at android.app.ActivityThread.-wrap20(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1726)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:171)
        at android.app.ActivityThread.main(ActivityThread.java:6684)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:246)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:783)

发现了一个问题,我先点击startService,再点击startMore,但startMore是等5s后再执行的,等了一个onStartCommond的时间,说明:startForegroundService是同步的(阻塞),startService是异步的(命令一次性下发,不阻塞)

anr log

07-14 14:37:36.339 1539-1590/? E/ActivityManager: ANR in com.example.demo_69_service
    PID: 7526
    Reason: executing service com.example.demo_69_service/.MyService
    Load: 0.08 / 0.09 / 0.04
    CPU usage from 0ms to 6928ms later (2018-07-14 14:37:29.374 to 2018-07-14 14:37:36.303):
      25% 1539/system_server: 14% user + 11% kernel / faults: 1956 minor
      2.5% 2256/com.android.phone: 2% user + 0.4% kernel / faults: 245 minor
      1.9% 913/media.codec: 0.8% user + 1% kernel / faults: 2128 minor
      0.5% 5156/com.sohu.inputmethod.sogou.xiaomi: 0.5% user + 0% kernel / faults: 358 minor
      2.6% 4780/kworker/u16:7: 0% user + 2.6% kernel
      0.7% 907/media.extractor: 0.3% user + 0.3% kernel / faults: 1786 minor
      1.4% 7526/com.example.demo_69_service: 1% user + 0.4% kernel / faults: 867 minor
      0.2% 3052/com.android.nfc: 0.1% user + 0.1% kernel / faults: 241 minor
      1% 5403/kworker/u16:13: 0% user + 1% kernel
      0.8% 564/logd: 0.4% user + 0.4% kernel
      0.7% 436/cfinteractive: 0% user + 0.7% kernel
      0.5% 773/surfaceflinger: 0.4% user + 0.1% kernel / faults: 366 minor
      0.5% 7323/adbd: 0% user + 0.5% kernel / faults: 116 minor
      0.4% 743/aaa@qq.com: 0.1% user + 0.2% kernel
      0.4% 2563/mcd: 0.1% user + 0.2% kernel
      0.4% 8479/com.android.bluetooth: 0.1% user + 0.2% kernel / faults: 108 minor
      0.1% 7/rcu_preempt: 0% user + 0.1% kernel
      0.2% 81/smem_native_rpm: 0% user + 0.2% kernel
      0% 929/tombstoned: 0% user + 0% kernel
      0.2% 2979/cnss_diag: 0.1% user + 0.1% kernel
      0.2% 6917/kworker/u16:8: 0% user + 0.2% kernel
      0.2% 30554/com.tencent.mm:tools: 0.2% user + 0% kernel
      0% 1//init: 0% user + 0% kernel
      0.1% 3/ksoftirqd/0: 0% user + 0.1% kernel
      0% 10/rcuop/0: 0% user + 0% kernel
      0.1% 15/ksoftirqd/1: 0% user + 0.1% kernel
      0% 53/rcuop/6: 0% user + 0% kernel
      0.1% 278/kgsl_worker_thr: 0% user + 0.1% kernel
      0% 347/kworker/u17:0: 0% user + 0% kernel
      0% 550/jbd2/sda17-8: 0% user + 0% kernel
      0% 572/kauditd: 0% user + 0% kernel
      0.1% 737/aaa@qq.com: 0.1% user + 0% kernel
      0.1% 749/aaa@qq.com: 0% user + 0.1% kernel
      0.1% 888/thermal-engine: 0% user + 0.1% kernel
      0% 899/audioserver: 0% user + 0% kernel / faults: 31 minor
      0% 901/cameraserver: 0% user + 0% kernel / faults: 28 minor
      0% 902/drmserver: 0% user + 0% kernel / faults: 38 minor
      0% 910/mediaserver: 0% user + 0% kernel / faults: 28 minor
      0.1% 993/msm_irqbalance: 0% user + 0.1% kernel
      0.1% 1416/kworker/u17:1: 0% user + 0.1% kernel
      0.1% 1863/cds_mc_thread: 0% user + 0.1% kernel
      0% 3831/kworker/5:3: 0% user + 0% kernel
      0.1% 5127/kworker/1:3: 0% user + 0.1% kernel
      0.1% 7030/mdss_fb0: 0% user + 0.1% kernel
      0.1% 7580/logcat: 0% user + 0.1% kernel
      0.1% 30111/com.tencent.mm:exdevice: 0% user + 0.1% kernel
    9% TOTAL: 4.8% user + 3.8% kernel + 0.1% iowait + 0% irq + 0.1% softirq
    CPU usage from 6347ms to 6873ms later (2018-07-14 14:37:35.721 to 2018-07-14 14:37:36.248) with 99% awake:
      7.3% 1539/system_server: 1.8% user + 5.4% kernel
        7.3% 1590/ActivityManager: 3.6% user + 3.6% kernel
      2.9% 4780/kworker/u16:7: 0% user + 2.9% kernel
      1.1% 743/aaa@qq.com: 0% user + 1.1% kernel
        1.1% 1829/HwBinder:743_1: 0% user + 1.1% kernel
    1.8% TOTAL: 0% user + 1.6% kernel + 0.2% softirq

traces.txt正好打印出了耗时操作,美滋滋

----- pid 7526 at 2018-07-14 14:37:29 -----
Cmd line: com.example.demo_69_service

 

"main" prio=5 tid=1 Sleeping
  | group="main" sCount=1 dsCount=0 flags=1 obj=0x731df7d0 self=0x76efe14c00
  | sysTid=7526 nice=-10 cgrp=default sched=0/0 handle=0x76f45d29b0
  | state=S schedstat=( 0 0 0 ) utm=48 stm=5 core=0 HZ=100
  | stack=0x7fc9d01000-0x7fc9d03000 stackSize=8MB
  | held mutexes=
  at java.lang.Thread.sleep(Native method)
  - sleeping on <0x048da97c> (a java.lang.Object)
  at java.lang.Thread.sleep(Thread.java:373)
  - locked <0x048da97c> (a java.lang.Object)
  at java.lang.Thread.sleep(Thread.java:314)
  at com.example.demo_69_service.MyService.onStartCommand(MyService.java:52)
  at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3577)
  at android.app.ActivityThread.-wrap20(ActivityThread.java:-1)
  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1726)
  at android.os.Handler.dispatchMessage(Handler.java:105)
  at android.os.Looper.loop(Looper.java:171)
  at android.app.ActivityThread.main(ActivityThread.java:6684)
  at java.lang.reflect.Method.invoke(Native method)
  at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:246)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:783)

9s到29s正好20s导致Service anr

结论:Service不可不间断调用onStartCommand工作20s及以上,否则anr,或者说activity不可不间断startService作耗时操作。(完成一个任务是不会remove掉第一个任务刚开始执行的timeout消息的,会判断是否都执行完才remove)

 

 

 

3.6 bind service以后调用Service方法,其中一方法耗时20s+,会不会导致Service anr

修改:

        Button btnSomeWork = findViewById(R.id.buttonDoWork);
        btnSomeWork.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (myService != null){
                    myService.doSomeWork();
                }
            }
        });

Service:

    public void doSomeWork(){
        Log.d(TAG, "doSomeWork begin");
        try {
            Thread.sleep(25000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Log.d(TAG, "doSomeWork end");
    }

 

log:

 

07-14 14:49:42.937 8209-8209/com.example.demo_69_service D/demo69_service: doSomeWork begin
07-14 14:50:07.941 8209-8209/com.example.demo_69_service D/demo69_service: doSomeWork end

现象:不会anr,和框架中只监控create、bind、start过程一致。

这只是模拟在monkey或者负载比较高时某些方法比较耗时情况下Service是否会anr,正确做法是耗时操作用IntentService或者另起一个线程。

 

3.7 onServiceConnected中有耗时20s+操作,是否anr

修改

    private ServiceConnection conn = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d(TAG, "onServiceConnected", new RuntimeException());
            try {
                Thread.sleep(25000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Log.d(TAG, "onServiceConnected 25s later");
            isBound = true;
            MyService.MyBinder binder = (MyService.MyBinder) service;
            myService = binder.getService();
        }

        //client 和service连接意外丢失时,会调用该方法
        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d(TAG, "onServiceDisconnected", new RuntimeException());
        }

    };

log:

07-14 14:56:58.922 8920-8920/com.example.demo_69_service D/demo69_service: onCreate
    java.lang.RuntimeException
        at com.example.demo_69_service.MyService.onCreate(MyService.java:31)
        at android.app.ActivityThread.handleCreateService(ActivityThread.java:3442)
        at android.app.ActivityThread.-wrap4(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1711)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:171)
        at android.app.ActivityThread.main(ActivityThread.java:6684)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:246)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:783)
07-14 14:56:58.933 8920-8920/com.example.demo_69_service D/demo69_service: onBind
    java.lang.RuntimeException
        at com.example.demo_69_service.MyService.onBind(MyService.java:38)
        at android.app.ActivityThread.handleBindService(ActivityThread.java:3469)
        at android.app.ActivityThread.-wrap2(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1716)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:171)
        at android.app.ActivityThread.main(ActivityThread.java:6684)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:246)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:783)
07-14 14:56:58.935 8920-8920/com.example.demo_69_service D/demo69_activity: onServiceConnected
    java.lang.RuntimeException
        at com.example.demo_69_service.MainActivity$1.onServiceConnected(MainActivity.java:22)
        at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1645)
        at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1674)
        at android.os.Handler.handleCallback(Handler.java:789)
        at android.os.Handler.dispatchMessage(Handler.java:98)
        at android.os.Looper.loop(Looper.java:171)
        at android.app.ActivityThread.main(ActivityThread.java:6684)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:246)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:783)
07-14 14:57:23.940 8920-8920/com.example.demo_69_service D/demo69_activity: onServiceConnected 25s later

 

结论:不会anr

 

 

3.8 bind service是否必须等待onServiceConnected被调用

修改

        Button btnForBindService = findViewById(R.id.buttonBind);
        btnForBindService.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                bindService(serviceIntent, conn, BIND_AUTO_CREATE);
                Log.d(TAG, "bindService success :");
            }
        });
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d(TAG, "onServiceConnected", new RuntimeException());
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Log.d(TAG, "onServiceConnected 5s later");
            isBound = true;
            MyService.MyBinder binder = (MyService.MyBinder) service;
            myService = binder.getService();
        }

 

log:

 

07-14 15:02:58.042 9315-9315/com.example.demo_69_service D/demo69_activity: bindService success :
07-14 15:02:58.064 9315-9315/com.example.demo_69_service D/demo69_service: onCreate
    java.lang.RuntimeException
        at com.example.demo_69_service.MyService.onCreate(MyService.java:31)
        at android.app.ActivityThread.handleCreateService(ActivityThread.java:3442)
        at android.app.ActivityThread.-wrap4(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1711)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:171)
        at android.app.ActivityThread.main(ActivityThread.java:6684)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:246)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:783)
07-14 15:02:58.076 9315-9315/com.example.demo_69_service D/demo69_service: onBind
    java.lang.RuntimeException
        at com.example.demo_69_service.MyService.onBind(MyService.java:38)
        at android.app.ActivityThread.handleBindService(ActivityThread.java:3469)
        at android.app.ActivityThread.-wrap2(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1716)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:171)
        at android.app.ActivityThread.main(ActivityThread.java:6684)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:246)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:783)
07-14 15:02:58.083 9315-9315/com.example.demo_69_service D/demo69_activity: onServiceConnected
    java.lang.RuntimeException
        at com.example.demo_69_service.MainActivity$1.onServiceConnected(MainActivity.java:22)
        at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1645)
        at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1674)
        at android.os.Handler.handleCallback(Handler.java:789)
        at android.os.Handler.dispatchMessage(Handler.java:98)
        at android.os.Looper.loop(Looper.java:171)
        at android.app.ActivityThread.main(ActivityThread.java:6684)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:246)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:783)
07-14 15:03:03.085 9315-9315/com.example.demo_69_service D/demo69_activity: onServiceConnected 5s later

结论:bindService一旦调用是不会等流程结束的,主线程会继续往下走,即不管onServiceConnected有没有被调用都不影响后面逻辑的执行。但是onServiceConnected还是执行在主线程的,不能进行耗时操作,会导致主线程anr。

07-15 11:22:30.029 8808-8808/com.example.demo_69_service D/demo69_activity: onCreateThread[main,5,main]



07-15 11:22:46.761 8808-8808/com.example.demo_69_service D/demo69_activity: bindService success :
07-15 11:22:46.778 8808-8808/com.example.demo_69_service D/demo69_service: onCreateThread[main,5,main]
    java.lang.RuntimeException
        at com.example.demo_69_service.MyService.onCreate(MyService.java:31)
        at android.app.ActivityThread.handleCreateService(ActivityThread.java:3442)
        at android.app.ActivityThread.-wrap4(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1711)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:171)
        at android.app.ActivityThread.main(ActivityThread.java:6684)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:246)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:783)
07-15 11:22:46.791 8808-8808/com.example.demo_69_service D/demo69_service: onBindThread[main,5,main]
    java.lang.RuntimeException
        at com.example.demo_69_service.MyService.onBind(MyService.java:38)
        at android.app.ActivityThread.handleBindService(ActivityThread.java:3469)
        at android.app.ActivityThread.-wrap2(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1716)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:171)
        at android.app.ActivityThread.main(ActivityThread.java:6684)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:246)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:783)
07-15 11:22:46.795 8808-8808/com.example.demo_69_service D/demo69_activity: onServiceConnectedThread[main,5,main]
    java.lang.RuntimeException
        at com.example.demo_69_service.MainActivity$1.onServiceConnected(MainActivity.java:22)
        at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1645)
        at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1674)
        at android.os.Handler.handleCallback(Handler.java:789)
        at android.os.Handler.dispatchMessage(Handler.java:98)
        at android.os.Looper.loop(Looper.java:171)
        at android.app.ActivityThread.main(ActivityThread.java:6684)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:246)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:783)
07-15 11:22:51.797 8808-8808/com.example.demo_69_service D/demo69_activity: onServiceConnected 5s later

这里需要再结合源码看一下:

onServiceConnected

        public void connected(ComponentName name, IBinder service, boolean dead) {
            if (mActivityThread != null) {
                mActivityThread.post(new RunConnection(name, service, 0, dead));
            } else {
                doConnected(name, service, dead);
            }
        }

从堆栈来看走到mActivityThread.post方法中去了。

可以参考Android中bindService的细节之二:从进程的角度分析绑定Service的流程【Service所在进程已存在】

这篇对线程切换讲的很清楚,也解释了上面的流程现象。

(六十九) 探究如何让Service anr?

(六十九) 探究如何让Service anr?

4. 总结

 

  • 在onCreate或者onStartCommand或者onBind或者onUnbind或者onDestroy中执行20s+(200s+)的操作
  • 在onStartCommand 持续进行累计20s+(200s+)的操作
  • 调用Service的某个耗时方法不会造成anr

 

ActiveServices.java

requestServiceBindingLocked: bumpServiceExecutingLocked(r, execInFg, "bind");

 realStartServiceLocked:bumpServiceExecutingLocked(r, execInFg, "bind");

sendServiceArgsLocked: bumpServiceExecutingLocked(r, execInFg, "start");

bringDownServiceLocked:bumpServiceExecutingLocked(r, false, "bring down unbind");

 bringDownServiceLocked:bumpServiceExecutingLocked(r, false, "destroy");

removeConnectionLocked:  bumpServiceExecutingLocked(s, false, "unbind");

相关标签: Service