package com.taobao.android; import android.app.Activity; import android.app.Application; import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.ResolveInfo; import android.os.Build; import android.os.Bundle; import android.os.Looper; import android.support.v4.app.FragmentActivity; import android.taobao.atlas.bundleInfo.AtlasBundleInfoManager; import android.taobao.atlas.framework.Atlas; import android.taobao.atlas.framework.BundleImpl; import android.taobao.atlas.framework.Framework; import android.taobao.atlas.runtime.ActivityTaskMgr; import android.taobao.atlas.runtime.BundleUtil; import android.taobao.atlas.runtime.RuntimeVariables; import android.taobao.atlas.util.StringUtils; import android.text.TextUtils; import android.util.Log; import android.view.ViewGroup; /** * Created by guanjie on 16/11/16. */ public class ActivityGroupDelegate { private static final String STATES_KEY = "android:states"; private LocalActivityManager mLocalActivityManager; private FragmentActivity mActivity; public LocalActivityManager getLocalActivityManager(){ return mLocalActivityManager; } public ActivityGroupDelegate(FragmentActivity activity, Bundle bundle){ mActivity = activity; try { mLocalActivityManager = new LocalActivityManager(activity, true); }catch(Throwable e){ throw new RuntimeException(e); } // Bundle states = bundle != null // ? (Bundle) bundle.getBundle(STATES_KEY) : null; mLocalActivityManager.dispatchCreate(null); activity.getApplication().registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() { @Override public void onActivityCreated(Activity activity, Bundle bundle) { } @Override public void onActivityStarted(Activity activity) { } @Override public void onActivityResumed(Activity activity) { if(mActivity == activity) { mLocalActivityManager.dispatchResume(); } } @Override public void onActivityPaused(Activity activity) { if(mActivity == activity) { mLocalActivityManager.dispatchPause(mActivity.isFinishing()); } } @Override public void onActivityStopped(Activity activity) { if(mActivity == activity) { mLocalActivityManager.dispatchStop(); } } @Override public void onActivitySaveInstanceState(Activity activity, Bundle bundle) { if(mActivity == activity) { Bundle state = mLocalActivityManager.saveInstanceState(); if (state != null) { bundle.putBundle(STATES_KEY, state); } } } @Override public void onActivityDestroyed(Activity activity) { if(mActivity == activity) { mLocalActivityManager.removeAllActivities(); } } }); } // public HashMap<String,Object> onRetainNonConfigurationChildInstances() { // if(dispatchRetainNonConfigurationInstanceMethod!=null) { // try { // return (HashMap<String, Object>) dispatchRetainNonConfigurationInstanceMethod.invoke(mLocalActivityManager); // } catch (Throwable e) { // e.printStackTrace(); // } // } // return null; // } // private static Method dispatchRetainNonConfigurationInstanceMethod = null; // private static Method onActivityResultMethod = null; // private static Method noteStateNotSavedMethod = null; // private static Method findFragmentByWhoMethod = null; // static{ // try { // dispatchRetainNonConfigurationInstanceMethod = LocalActivityManager.class.getDeclaredMethod("dispatchRetainNonConfigurationInstance"); // dispatchRetainNonConfigurationInstanceMethod.setAccessible(true); // onActivityResultMethod = Activity.class.getDeclaredMethod("onActivityResult",int.class,int.class,Intent.class); // onActivityResultMethod.setAccessible(true); // noteStateNotSavedMethod = Class.forName("android.support.v4.app.FragmentManagerImpl"). // getDeclaredMethod("noteStateNotSaved"); // noteStateNotSavedMethod.setAccessible(true); // findFragmentByWhoMethod = Class.forName("android.support.v4.app.FragmentManagerImpl"). // getDeclaredMethod("findFragmentByWho",String.class); // findFragmentByWhoMethod.setAccessible(true); // } catch (Throwable e) { // e.printStackTrace(); // } // // } public void startChildActivity(ViewGroup container, String key, Intent intent){ //移除内容部分全部的View container.removeAllViews(); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); Activity contentActivity = mLocalActivityManager.getActivity(key); if(contentActivity!=null) { container.addView( mLocalActivityManager.getActivity(key) .getWindow().getDecorView(), new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); mLocalActivityManager.switchToChildActivity(key); }else{ execStartChildActivityInternal(container, key, intent); } } private void performLaunchChildActivity(ViewGroup container,String key,Intent intent ){ if(intent==null){ Log.e("ActivityGroupDelegate","intent is null stop performLaunchChildActivity"); return ; } mLocalActivityManager.startActivity(key,intent); container.addView( mLocalActivityManager.getActivity(key) .getWindow().getDecorView(), new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); } public void execStartChildActivityInternal(ViewGroup container,String key, Intent intent){ String packageName = null; String componentName = null ; Context context = container.getContext(); if (intent.getComponent() != null) { packageName = intent.getComponent().getPackageName(); componentName = intent.getComponent().getClassName(); } else { ResolveInfo resolveInfo = context.getPackageManager().resolveActivity(intent, 0); if (resolveInfo != null && resolveInfo.activityInfo != null) { packageName = resolveInfo.activityInfo.packageName; componentName = resolveInfo.activityInfo.name; } } if (componentName == null){ Log.e("ActivityGroupDelegate","can not find componentName"); } if (!StringUtils.equals(context.getPackageName(), packageName)) { Log.e("ActivityGroupDelegate","childActivity can not be external Activity"); } String bundleName = AtlasBundleInfoManager.instance().getBundleForComponet(componentName); if(!TextUtils.isEmpty(bundleName)){ BundleImpl impl = (BundleImpl) Atlas.getInstance().getBundle(bundleName); if(impl!=null&&impl.checkValidate()) { performLaunchChildActivity(container,key,intent); }else { if(ActivityTaskMgr.getInstance().peekTopActivity()!=null && Looper.getMainLooper().getThread().getId()==Thread.currentThread().getId()) { asyncStartActivity(container,key,bundleName,intent); }else{ performLaunchChildActivity(container,key,intent); } } }else{ // Try to get class from system Classloader try { Class<?> clazz = null; clazz = Framework.getSystemClassLoader().loadClass(componentName); if (clazz != null) { performLaunchChildActivity(container,key,intent); } } catch (ClassNotFoundException e) { Log.e("ActivityGroupDelegate",e.getCause().toString()); } } } private void asyncStartActivity(final ViewGroup container,final String key,final String bundleName,final Intent intent){ final Activity current = ActivityTaskMgr.getInstance().peekTopActivity(); final Dialog dialog = current!=null ? RuntimeVariables.alertDialogUntilBundleProcessed(current,bundleName) : null; if(current!=null && dialog==null){ throw new RuntimeException("alertDialogUntilBundleProcessed can not return null"); } final int currentActivitySize = ActivityTaskMgr.getInstance().sizeOfActivityStack(); final BundleUtil.CancelableTask successTask = new BundleUtil.CancelableTask(new Runnable() { @Override public void run() { if (current == ActivityTaskMgr.getInstance().peekTopActivity() || currentActivitySize==ActivityTaskMgr.getInstance().sizeOfActivityStack()+1) { performLaunchChildActivity(container,key,intent); } if (dialog != null && current != null && !current.isFinishing()) { try { if(dialog.isShowing()) dialog.dismiss(); }catch (Throwable e){} } } }); final BundleUtil.CancelableTask failedTask = new BundleUtil.CancelableTask(new Runnable() { @Override public void run() { if (current == ActivityTaskMgr.getInstance().peekTopActivity()) { } if (dialog != null && current != null && !current.isFinishing()) { try { if(dialog.isShowing()) dialog.dismiss(); }catch(Throwable e){} } } }); if(dialog!=null) { dialog.setOnDismissListener(new DialogInterface.OnDismissListener() { @Override public void onDismiss(DialogInterface dialog) { successTask.cancel(); failedTask.cancel(); } }); if(Atlas.getInstance().getBundle(bundleName)==null || Build.VERSION.SDK_INT<22) { if (dialog != null && current != null && !current.isFinishing() && !dialog.isShowing()) { try { dialog.show(); } catch (Throwable e) { } } } BundleUtil.checkBundleStateAsync(bundleName, successTask, failedTask); } } }