Skip to content

Commit 820ad84

Browse files
committed
see 04/01 log
1 parent 2fb08e2 commit 820ad84

File tree

5 files changed

+102
-73
lines changed

5 files changed

+102
-73
lines changed

.github/workflows/android.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@ jobs:
1414
with:
1515
java-version: 1.8
1616
- name: Build with Gradle
17-
run: ./gradlew build
17+
run: ./gradlew aR

.travis.yml

Lines changed: 0 additions & 24 deletions
This file was deleted.

lib/utilcode/src/main/java/com/blankj/utilcode/util/IntentUtils.java

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -100,17 +100,12 @@ public static Intent getUninstallAppIntent(final String pkgName) {
100100
* @return the intent of launch app
101101
*/
102102
public static Intent getLaunchAppIntent(final String pkgName) {
103-
// String launcherActivity = UtilsBridge.getLauncherActivity(pkgName);
104-
// LogUtils.e(launcherActivity);
105-
// if (UtilsBridge.isSpace(launcherActivity)) return null;
106-
// Intent intent = new Intent(Intent.ACTION_MAIN);
107-
// intent.addCategory(Intent.CATEGORY_LAUNCHER);
108-
// intent.setClassName(pkgName, launcherActivity);
109-
// return intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
110-
111-
Intent intent = Utils.getApp().getPackageManager().getLaunchIntentForPackage(pkgName);
112-
if (intent == null) return null;
113-
return getIntent(intent, true);
103+
String launcherActivity = UtilsBridge.getLauncherActivity(pkgName);
104+
if (UtilsBridge.isSpace(launcherActivity)) return null;
105+
Intent intent = new Intent(Intent.ACTION_MAIN);
106+
intent.addCategory(Intent.CATEGORY_LAUNCHER);
107+
intent.setClassName(pkgName, launcherActivity);
108+
return intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
114109
}
115110

116111
/**

lib/utilcode/src/main/java/com/blankj/utilcode/util/UtilsActivityLifecycleImpl.java

Lines changed: 93 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package com.blankj.utilcode.util;
22

33
import android.animation.ValueAnimator;
4-
import android.annotation.SuppressLint;
54
import android.app.Activity;
65
import android.app.Application;
76
import android.arch.lifecycle.Lifecycle;
@@ -35,7 +34,7 @@ final class UtilsActivityLifecycleImpl implements Application.ActivityLifecycleC
3534

3635
static final UtilsActivityLifecycleImpl INSTANCE = new UtilsActivityLifecycleImpl();
3736

38-
final LinkedList<Activity> mActivityList = new LinkedList<>();
37+
private final LinkedList<Activity> mActivityList = new LinkedList<>();
3938

4039
private final List<Utils.OnAppStatusChangedListener> mStatusListeners = new ArrayList<>();
4140
private final Map<Activity, List<Utils.OnActivityDestroyedListener>> mDestroyedListenerMap = new HashMap<>();
@@ -51,20 +50,23 @@ void init() {
5150
}
5251

5352
Activity getTopActivity() {
54-
if (!mActivityList.isEmpty()) {
55-
for (int i = mActivityList.size() - 1; i >= 0; i--) {
56-
Activity activity = mActivityList.get(i);
57-
if (!UtilsBridge.isActivityAlive(activity)) {
58-
continue;
59-
}
60-
return activity;
53+
List<Activity> activityList = getActivityList();
54+
for (Activity activity : activityList) {
55+
if (!UtilsBridge.isActivityAlive(activity)) {
56+
continue;
6157
}
58+
return activity;
6259
}
63-
Activity topActivityByReflect = getTopActivityByReflect();
64-
if (topActivityByReflect != null) {
65-
setTopActivity(topActivityByReflect);
60+
return null;
61+
}
62+
63+
List<Activity> getActivityList() {
64+
if (!mActivityList.isEmpty()) {
65+
return mActivityList;
6666
}
67-
return topActivityByReflect;
67+
List<Activity> reflectActivities = getActivitiesByReflect();
68+
mActivityList.addAll(reflectActivities);
69+
return mActivityList;
6870
}
6971

7072
void addOnAppStatusChangedListener(final Utils.OnAppStatusChangedListener listener) {
@@ -240,12 +242,12 @@ private void postStatus(final Activity activity, final boolean isForeground) {
240242

241243
private void setTopActivity(final Activity activity) {
242244
if (mActivityList.contains(activity)) {
243-
if (!mActivityList.getLast().equals(activity)) {
245+
if (!mActivityList.getFirst().equals(activity)) {
244246
mActivityList.remove(activity);
245-
mActivityList.addLast(activity);
247+
mActivityList.addFirst(activity);
246248
}
247249
} else {
248-
mActivityList.addLast(activity);
250+
mActivityList.addFirst(activity);
249251
}
250252
}
251253

@@ -292,29 +294,86 @@ private void consumeActivityLifecycleCallbacks(Activity activity, Lifecycle.Even
292294
}
293295
}
294296

295-
private Activity getTopActivityByReflect() {
297+
private List<Activity> getActivitiesByReflect() {
298+
LinkedList<Activity> list = new LinkedList<>();
299+
Activity topActivity = null;
296300
try {
297-
@SuppressLint("PrivateApi")
298-
Class<?> activityThreadClass = Class.forName("android.app.ActivityThread");
299-
Object currentActivityThreadMethod = activityThreadClass.getMethod("currentActivityThread").invoke(null);
300-
Field mActivityListField = activityThreadClass.getDeclaredField("mActivityList");
301-
mActivityListField.setAccessible(true);
302-
Map activities = (Map) mActivityListField.get(currentActivityThreadMethod);
303-
if (activities == null) return null;
304-
for (Object activityRecord : activities.values()) {
305-
Class activityRecordClass = activityRecord.getClass();
306-
Field pausedField = activityRecordClass.getDeclaredField("paused");
307-
pausedField.setAccessible(true);
308-
if (!pausedField.getBoolean(activityRecord)) {
309-
Field activityField = activityRecordClass.getDeclaredField("activity");
310-
activityField.setAccessible(true);
311-
return (Activity) activityField.get(activityRecord);
301+
Object activityThread = getActivityThread();
302+
Field mActivitiesField = activityThread.getClass().getDeclaredField("mActivities");
303+
mActivitiesField.setAccessible(true);
304+
Object mActivities = mActivitiesField.get(activityThread);
305+
if (!(mActivities instanceof Map)) {
306+
return list;
307+
}
308+
Map<Object, Object> binder_activityClientRecord_map = (Map<Object, Object>) mActivities;
309+
for (Object activityRecord : binder_activityClientRecord_map.values()) {
310+
Class activityClientRecordClass = activityRecord.getClass();
311+
Field activityField = activityClientRecordClass.getDeclaredField("activity");
312+
activityField.setAccessible(true);
313+
Activity activity = (Activity) activityField.get(activityRecord);
314+
if (topActivity == null) {
315+
Field pausedField = activityClientRecordClass.getDeclaredField("paused");
316+
pausedField.setAccessible(true);
317+
if (!pausedField.getBoolean(activityRecord)) {
318+
topActivity = activity;
319+
} else {
320+
list.add(activity);
321+
}
322+
} else {
323+
list.add(activity);
312324
}
313325
}
314326
} catch (Exception e) {
315-
Log.e("UtilsActivityLifecycle", e.getMessage());
327+
Log.e("UtilsActivityLifecycle", "getActivitiesByReflect: " + e.getMessage());
328+
}
329+
if (topActivity != null) {
330+
list.addFirst(topActivity);
331+
}
332+
return list;
333+
}
334+
335+
private Object getActivityThread() {
336+
Object activityThread = getActivityThreadInActivityThreadStaticField();
337+
if (activityThread != null) return activityThread;
338+
activityThread = getActivityThreadInActivityThreadStaticMethod();
339+
if (activityThread != null) return activityThread;
340+
return getActivityThreadInLoadedApkField();
341+
}
342+
343+
private Object getActivityThreadInActivityThreadStaticField() {
344+
try {
345+
Class activityThreadClass = Class.forName("android.app.ActivityThread");
346+
Field sCurrentActivityThreadField = activityThreadClass.getDeclaredField("sCurrentActivityThread");
347+
sCurrentActivityThreadField.setAccessible(true);
348+
return sCurrentActivityThreadField.get(null);
349+
} catch (Exception e) {
350+
Log.e("UtilsActivityLifecycle", "getActivityThreadInActivityThreadStaticField: " + e.getMessage());
351+
return null;
352+
}
353+
}
354+
355+
private Object getActivityThreadInActivityThreadStaticMethod() {
356+
try {
357+
Class activityThreadClass = Class.forName("android.app.ActivityThread");
358+
return activityThreadClass.getMethod("currentActivityThread").invoke(null);
359+
} catch (Exception e) {
360+
Log.e("UtilsActivityLifecycle", "getActivityThreadInActivityThreadStaticMethod: " + e.getMessage());
361+
return null;
362+
}
363+
}
364+
365+
private Object getActivityThreadInLoadedApkField() {
366+
try {
367+
Field mLoadedApkField = Application.class.getDeclaredField("mLoadedApk");
368+
mLoadedApkField.setAccessible(true);
369+
Object mLoadedApk = mLoadedApkField.get(Utils.getApp());
370+
Field mActivityThreadField = mLoadedApk.getClass().getDeclaredField("mActivityThread");
371+
mActivityThreadField.setAccessible(true);
372+
return mActivityThreadField.get(mLoadedApk);
373+
} catch (Exception e) {
374+
Log.e("UtilsActivityLifecycle", "getActivityThreadInLoadedApkField: " + e.getMessage());
375+
return null;
316376
}
317-
return null;
318377
}
319378

320379
/**

lib/utilcode/src/main/java/com/blankj/utilcode/util/UtilsBridge.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import java.io.InputStream;
2121
import java.io.Serializable;
2222
import java.lang.reflect.Type;
23-
import java.util.LinkedList;
2423
import java.util.List;
2524

2625
import static android.Manifest.permission.CALL_PHONE;
@@ -69,8 +68,8 @@ static void removeActivityLifecycleCallbacks(final Activity activity,
6968
UtilsActivityLifecycleImpl.INSTANCE.removeActivityLifecycleCallbacks(activity, callbacks);
7069
}
7170

72-
static LinkedList<Activity> getActivityList() {
73-
return UtilsActivityLifecycleImpl.INSTANCE.mActivityList;
71+
static List<Activity> getActivityList() {
72+
return UtilsActivityLifecycleImpl.INSTANCE.getActivityList();
7473
}
7574

7675
///////////////////////////////////////////////////////////////////////////

0 commit comments

Comments
 (0)