package com.gh.common.util; import static com.gh.gamecenter.common.constant.EntranceConsts.KEY_NEXT_TO; import static com.gh.gamecenter.common.constant.EntranceConsts.KEY_REQUIRE_REDIRECT; import static com.gh.gamecenter.common.constant.EntranceConsts.KEY_TO; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.os.Build; import android.os.Bundle; import android.os.Parcelable; import android.text.TextUtils; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import com.gh.gamecenter.BuildConfig; import com.gh.gamecenter.MainActivity; import com.gh.gamecenter.SplashScreenActivity; import com.gh.gamecenter.common.avoidcallback.AvoidOnResultManager; import com.gh.gamecenter.common.avoidcallback.Callback; import com.gh.gamecenter.common.base.activity.ToolBarActivity; import com.gh.gamecenter.common.base.fragment.ToolbarFragment; import com.gh.gamecenter.common.constant.EntranceConsts; import com.gh.gamecenter.core.utils.ClassUtils; import com.gh.gamecenter.core.utils.GsonUtils; import com.gh.gamecenter.core.utils.SPUtils; import com.halo.assistant.HaloApp; import com.lightgame.utils.Utils; import org.json.JSONException; import org.json.JSONObject; import java.util.Iterator; import java.util.Set; public class EntranceUtils { public static void jumpActivity(Context context, Bundle bundle) { jumpActivityCompat(context, bundle, null, null); } public static void jumpActivityCompat(Context context, Bundle bundle) { jumpActivityCompat(context, bundle, null,null); } public static void jumpActivityCompat(Context context, Bundle bundle, @Nullable Bundle nextToBundle, @Nullable Callback callback) { bundle.putBoolean(KEY_REQUIRE_REDIRECT, true); if (HaloApp.getInstance().isRunningForeground || HaloApp.getInstance().isAlreadyUpAndRunning) { // 应用正在运行,前台或后台 String to = bundle.getString(KEY_TO); Class clazz = ClassUtils.forName(to); if (clazz == null) clazz = MainActivity.class; if (ToolbarFragment.class.isAssignableFrom(clazz)) { // 兼容ToolbarFragment ToolBarActivity.startFragmentNewTask(context, (Class) clazz, bundle); } else if (callback != null ) { Intent intent1 = new Intent(context, clazz); //TODO:添加FLAG_ACTIVITY_NEW_TASK会导致一跳转页面callback就被调用 //intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent1.putExtras(bundle); if (context instanceof AppCompatActivity) { AvoidOnResultManager.Companion.getInstance((AppCompatActivity) context) .startForResult(intent1, callback); } else { // 不要回调,正常跳转 context.startActivity(intent1); } } else { Intent intent1 = new Intent(context, clazz); intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 如果 activity 名称有 singleton 的就添加 reorder_to_front 标签 (有点粗暴有点蠢,但暂时就先这样吧 :C ) if (clazz.getSimpleName().toLowerCase().contains("singleton")) { intent1.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); } intent1.putExtras(bundle); context.startActivity(intent1); } } else { // 应用未在运行 if (nextToBundle != null) { bundle.putBundle(KEY_NEXT_TO, nextToBundle); } context.startActivity(SplashScreenActivity.getSplashScreenIntent(context, bundle)); } } public static void saveShortcut(String activityName, @Nullable Bundle bundle) { if (BuildConfig.DEBUG) { if (activityName.contains("MainActivity")) { SPUtils.setString(EntranceConsts.KEY_BUNDLE, ""); return; } if (bundle == null) bundle = new Bundle(); try { JSONObject json = new JSONObject(); json.put(KEY_TO, activityName); json = getJsonFromBundle(bundle, json, null); Utils.toast(HaloApp.getInstance().getApplication(), "保存捷径成功"); SPUtils.setString(EntranceConsts.KEY_BUNDLE, json.toString()); } catch (Exception e) { e.printStackTrace(); SPUtils.setString(EntranceConsts.KEY_BUNDLE, ""); } } } /** * 将 Bundle 转为 Json */ private static JSONObject getJsonFromBundle(Bundle bundle, JSONObject json, @Nullable JSONObject bundleWrapper) throws JSONException { Set keys = bundle.keySet(); for (String key : keys) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { Object object = bundle.get(key); if (object instanceof Bundle) { json = getJsonFromBundle((Bundle) object, json, new JSONObject()); } else if (object instanceof Parcelable) { String parcelableName = key + ":parcelable"; String parcelableType = object.getClass().getName(); String objectJsonString = GsonUtils.toJson(object); JSONObject jObject = null; jObject = new JSONObject(objectJsonString); if (bundleWrapper != null) { bundleWrapper.put(parcelableName, parcelableType); bundleWrapper.put(key, jObject); } else { json.put(parcelableName, parcelableType); json.put(key, jObject); } } else { if (bundleWrapper != null) { bundleWrapper.put(key, JSONObject.wrap(bundle.get(key))); } else { json.put(key, JSONObject.wrap(bundle.get(key))); } } } } if (bundleWrapper != null) { json.put(":bundle", bundleWrapper); } return json; } /** * 快捷地跳转到上次保存的页面 */ public static void jumpShortcut(Activity activity) { if (BuildConfig.DEBUG) { if (!hasShortcut()) return; Bundle bundle = new Bundle(); try { JSONObject jsonObject = new JSONObject(SPUtils.getString(EntranceConsts.KEY_BUNDLE)); getBundleFromJson(bundle, jsonObject, null); } catch (Exception e) { e.printStackTrace(); } EntranceUtils.jumpActivity(activity, bundle); } } /** * 从 JSON 里还原 Bundle */ private static void getBundleFromJson(Bundle bundle, JSONObject jsonObject, @Nullable Bundle bundleWithin) throws JSONException, ClassNotFoundException { Iterator iter = jsonObject.keys(); String parcelableName = ""; while (iter.hasNext()) { String key = (String) iter.next(); String value = jsonObject.getString(key); if (key.contains(":parcelable")) { parcelableName = value; } else if (key.contains(":bundle")) { getBundleFromJson(bundle, new JSONObject(value), new Bundle()); } else { if (bundleWithin != null) { if (!TextUtils.isEmpty(parcelableName)) { Class gClass = Class.forName(parcelableName); bundleWithin.putParcelable(key, ((Parcelable) GsonUtils.fromJson(value, gClass))); } else { bundleWithin.putString(key, value); } // TODO 支持多层 bundle 嵌套 // TODO 直接用 GSON 提供的 Bundle Adapter https://github.com/google-gson/typeadapters/blob/master/android/src/main/java/BundleTypeAdapterFactory.java if (!bundle.containsKey("normalFragmentBundle")) { bundle.putBundle("normalFragmentBundle", bundleWithin); } } else { if (!TextUtils.isEmpty(parcelableName)) { Class gClass = Class.forName(parcelableName); bundle.putParcelable(key, ((Parcelable) GsonUtils.fromJson(value, gClass))); } else { bundle.putString(key, value); } } } } } public static boolean hasShortcut() { return !TextUtils.isEmpty(SPUtils.getString(EntranceConsts.KEY_BUNDLE)); } }