Skip to content

Commit 8c4c305

Browse files
committed
补充系统语种变化后应用也跟随变化的代码逻辑
1 parent baea5fe commit 8c4c305

File tree

2 files changed

+334
-2
lines changed

2 files changed

+334
-2
lines changed
Lines changed: 320 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,320 @@
1+
package com.hjq.language.demo;
2+
3+
import android.annotation.SuppressLint;
4+
import android.app.Activity;
5+
import android.app.Application;
6+
import android.content.Context;
7+
import android.os.Build;
8+
import android.os.Bundle;
9+
import android.text.TextUtils;
10+
11+
import androidx.annotation.NonNull;
12+
import androidx.annotation.Nullable;
13+
14+
import java.io.FileInputStream;
15+
import java.io.IOException;
16+
import java.lang.reflect.InvocationTargetException;
17+
import java.lang.reflect.Method;
18+
import java.nio.charset.StandardCharsets;
19+
import java.util.ArrayList;
20+
import java.util.Iterator;
21+
import java.util.List;
22+
23+
/**
24+
* author : Android 轮子哥
25+
* github : https://github.com/getActivity/AndroidProject
26+
* time : 2018/11/18
27+
* desc : Activity 管理器
28+
*/
29+
public final class ActivityManager implements Application.ActivityLifecycleCallbacks {
30+
31+
private static volatile ActivityManager sInstance;
32+
33+
/** Activity 存放集合 */
34+
private final List<Activity> mActivityList = new ArrayList<>();
35+
36+
/** 应用生命周期回调 */
37+
private final ArrayList<ApplicationLifecycleCallback> mLifecycleCallbacks = new ArrayList<>();
38+
39+
/** 当前应用上下文对象 */
40+
private Application mApplication;
41+
/** 栈顶的 Activity 对象 */
42+
private Activity mTopActivity;
43+
/** 前台并且可见的 Activity 对象 */
44+
private Activity mResumedActivity;
45+
46+
private ActivityManager() {}
47+
48+
public static ActivityManager getInstance() {
49+
if(sInstance == null) {
50+
synchronized (ActivityManager.class) {
51+
if(sInstance == null) {
52+
sInstance = new ActivityManager();
53+
}
54+
}
55+
}
56+
return sInstance;
57+
}
58+
59+
public void init(Application application) {
60+
mApplication = application;
61+
mApplication.registerActivityLifecycleCallbacks(this);
62+
}
63+
64+
/**
65+
* 获取 Application 对象
66+
*/
67+
@NonNull
68+
public Application getApplication() {
69+
return mApplication;
70+
}
71+
72+
/**
73+
* 获取栈顶的 Activity
74+
*/
75+
@Nullable
76+
public Activity getTopActivity() {
77+
return mTopActivity;
78+
}
79+
80+
/**
81+
* 获取前台并且可见的 Activity
82+
*/
83+
@Nullable
84+
public Activity getResumedActivity() {
85+
return mResumedActivity;
86+
}
87+
88+
/**
89+
* 获取 Activity 集合
90+
*/
91+
@NonNull
92+
public List<Activity> getActivityList() {
93+
return mActivityList;
94+
}
95+
96+
/**
97+
* 判断当前应用是否处于前台状态
98+
*/
99+
public boolean isForeground() {
100+
return getResumedActivity() != null;
101+
}
102+
103+
/**
104+
* 注册应用生命周期回调
105+
*/
106+
public void registerApplicationLifecycleCallback(ApplicationLifecycleCallback callback) {
107+
mLifecycleCallbacks.add(callback);
108+
}
109+
110+
/**
111+
* 取消注册应用生命周期回调
112+
*/
113+
public void unregisterApplicationLifecycleCallback(ApplicationLifecycleCallback callback) {
114+
mLifecycleCallbacks.remove(callback);
115+
}
116+
117+
/**
118+
* 销毁指定的 Activity
119+
*/
120+
public void finishActivity(Class<? extends Activity> clazz) {
121+
if (clazz == null) {
122+
return;
123+
}
124+
125+
Iterator<Activity> iterator = mActivityList.iterator();
126+
while (iterator.hasNext()) {
127+
Activity activity = iterator.next();
128+
if (!activity.getClass().equals(clazz)) {
129+
continue;
130+
}
131+
if (!activity.isFinishing()) {
132+
activity.finish();
133+
}
134+
iterator.remove();
135+
}
136+
}
137+
138+
/**
139+
* 销毁所有的 Activity
140+
*/
141+
public void finishAllActivities() {
142+
finishAllActivities((Class<? extends Activity>) null);
143+
}
144+
145+
/**
146+
* 销毁所有的 Activity
147+
*
148+
* @param classArray 白名单 Activity
149+
*/
150+
@SafeVarargs
151+
public final void finishAllActivities(Class<? extends Activity>... classArray) {
152+
Iterator<Activity> iterator = mActivityList.iterator();
153+
while (iterator.hasNext()) {
154+
Activity activity = iterator.next();
155+
boolean whiteClazz = false;
156+
if (classArray != null) {
157+
for (Class<? extends Activity> clazz : classArray) {
158+
if (activity.getClass().equals(clazz)) {
159+
whiteClazz = true;
160+
}
161+
}
162+
}
163+
if (whiteClazz) {
164+
continue;
165+
}
166+
// 如果不是白名单上面的 Activity 就销毁掉
167+
if (!activity.isFinishing()) {
168+
activity.finish();
169+
}
170+
iterator.remove();
171+
}
172+
}
173+
174+
@Override
175+
public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) {
176+
if (mActivityList.isEmpty()) {
177+
for (ApplicationLifecycleCallback callback : mLifecycleCallbacks) {
178+
callback.onApplicationCreate(activity);
179+
}
180+
}
181+
mActivityList.add(activity);
182+
mTopActivity = activity;
183+
}
184+
185+
@Override
186+
public void onActivityStarted(@NonNull Activity activity) {
187+
}
188+
189+
@Override
190+
public void onActivityResumed(@NonNull Activity activity) {
191+
if (mTopActivity == activity && mResumedActivity == null) {
192+
for (ApplicationLifecycleCallback callback : mLifecycleCallbacks) {
193+
callback.onApplicationForeground(activity);
194+
}
195+
}
196+
mTopActivity = activity;
197+
mResumedActivity = activity;
198+
}
199+
200+
@Override
201+
public void onActivityPaused(@NonNull Activity activity) {
202+
}
203+
204+
@Override
205+
public void onActivityStopped(@NonNull Activity activity) {
206+
if (mResumedActivity == activity) {
207+
mResumedActivity = null;
208+
}
209+
if (mResumedActivity == null) {
210+
for (ApplicationLifecycleCallback callback : mLifecycleCallbacks) {
211+
callback.onApplicationBackground(activity);
212+
}
213+
}
214+
}
215+
216+
@Override
217+
public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {
218+
}
219+
220+
@Override
221+
public void onActivityDestroyed(@NonNull Activity activity) {
222+
mActivityList.remove(activity);
223+
if (mTopActivity == activity) {
224+
mTopActivity = null;
225+
}
226+
if (mActivityList.isEmpty()) {
227+
for (ApplicationLifecycleCallback callback : mLifecycleCallbacks) {
228+
callback.onApplicationDestroy(activity);
229+
}
230+
}
231+
}
232+
233+
/**
234+
* 判断是否在主进程中
235+
*/
236+
public static boolean isMainProcess(Context context) {
237+
String processName = getProcessName();
238+
if (TextUtils.isEmpty(processName)) {
239+
// 如果获取不到进程名称,那么则将它当做主进程
240+
return true;
241+
}
242+
return TextUtils.equals(processName, context.getPackageName());
243+
}
244+
245+
/**
246+
* 获取当前进程名称
247+
*/
248+
@SuppressLint("PrivateApi, DiscouragedPrivateApi")
249+
@Nullable
250+
public static String getProcessName() {
251+
String processName = null;
252+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
253+
processName = Application.getProcessName();
254+
} else {
255+
try {
256+
Class<?> activityThread = Class.forName("android.app.ActivityThread");
257+
Method currentProcessNameMethod = activityThread.getDeclaredMethod("currentProcessName");
258+
processName = (String) currentProcessNameMethod.invoke(null);
259+
} catch (ClassNotFoundException | ClassCastException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
260+
e.printStackTrace();
261+
}
262+
}
263+
264+
if (!TextUtils.isEmpty(processName)) {
265+
return processName;
266+
}
267+
268+
// 利用 Linux 系统获取进程名
269+
FileInputStream inputStream = null;
270+
try {
271+
inputStream = new FileInputStream("/proc/self/cmdline");
272+
byte[] buffer = new byte[256];
273+
int len = 0;
274+
int b;
275+
while ((b = inputStream.read()) > 0 && len < buffer.length) {
276+
buffer[len++] = (byte) b;
277+
}
278+
if (len > 0) {
279+
return new String(buffer, 0, len, StandardCharsets.UTF_8);
280+
}
281+
} catch (IOException e) {
282+
e.printStackTrace();
283+
} finally {
284+
if (inputStream != null) {
285+
try {
286+
inputStream.close();
287+
} catch (IOException e) {
288+
e.printStackTrace();
289+
}
290+
}
291+
}
292+
return null;
293+
}
294+
295+
/**
296+
* 应用生命周期回调
297+
*/
298+
public interface ApplicationLifecycleCallback {
299+
300+
/**
301+
* 第一个 Activity 创建了
302+
*/
303+
void onApplicationCreate(Activity activity);
304+
305+
/**
306+
* 最后一个 Activity 销毁了
307+
*/
308+
void onApplicationDestroy(Activity activity);
309+
310+
/**
311+
* 应用从前台进入到后台
312+
*/
313+
void onApplicationBackground(Activity activity);
314+
315+
/**
316+
* 应用从后台进入到前台
317+
*/
318+
void onApplicationForeground(Activity activity);
319+
}
320+
}

app/src/main/java/com/hjq/language/demo/AppApplication.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
package com.hjq.language.demo;
22

3+
import android.app.Activity;
34
import android.app.Application;
45
import android.content.Context;
56
import android.util.Log;
6-
77
import com.hjq.language.MultiLanguages;
88
import com.hjq.language.OnLanguageListener;
99
import com.hjq.toast.Toaster;
10-
10+
import java.util.List;
1111
import java.util.Locale;
1212

1313
/**
@@ -27,6 +27,8 @@ public final class AppApplication extends Application {
2727
public void onCreate() {
2828
super.onCreate();
2929

30+
ActivityManager.getInstance().init(this);
31+
3032
// 初始化 Toast 框架
3133
Toaster.init(this);
3234

@@ -44,6 +46,16 @@ public void onAppLocaleChange(Locale oldLocale, Locale newLocale) {
4446
public void onSystemLocaleChange(Locale oldLocale, Locale newLocale) {
4547
Log.i("MultiLanguages", "监听到系统切换了语种,旧语种:" + oldLocale + ",新语种:" + newLocale +
4648
",是否跟随系统:" + MultiLanguages.isSystemLanguage(AppApplication.this));
49+
50+
if (!MultiLanguages.isSystemLanguage(AppApplication.this)) {
51+
return;
52+
}
53+
// 如需在系统切换语种后应用也要随之变化的,可以在这里获取所有的 Activity 并调用它的 recreate 方法
54+
// getAllActivity 只是演示代码,需要自行替换成项目已实现的方法,若项目中没有,请自行封装
55+
List<Activity> activityList = ActivityManager.getInstance().getActivityList();
56+
for (Activity activity : activityList) {
57+
activity.recreate();
58+
}
4759
}
4860
});
4961
}

0 commit comments

Comments
 (0)