Last active
June 28, 2019 10:35
-
-
Save SinaMN75/5ba5a45bb9cb814e8809b1d94a794f0f to your computer and use it in GitHub Desktop.
Easily StartActivity and Pass data...
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.developersian.util.extentions | |
import android.app.Activity | |
import android.content.ComponentName | |
import android.content.Context | |
import android.content.Intent | |
import android.os.Bundle | |
import androidx.core.app.ActivityOptionsCompat | |
import com.developersian.util.Utilities.Toolkit | |
class Activity() { | |
fun startActivity(clz: Class<out Activity>, vararg extra: Pair<String, Any>, enterAnim: Int = android.R.anim.slide_in_left, exitAnim: Int = android.R.anim.slide_out_right) { | |
val context = Toolkit.getTopActivityOrApp() | |
val bundle = Bundle() | |
for (i in extra) { | |
if (i.second is Boolean) bundle.putBoolean(i.first, i.second.toString().toBoolean()) | |
if (i.second is String) bundle.putString(i.first, i.second.toString()) | |
if (i.second is Int) bundle.putInt(i.first, i.second.toString().toInt()) | |
if (i.second is Float) bundle.putFloat(i.first, i.second.toString().toFloat()) | |
if (i.second is Double) bundle.putDouble(i.first, i.second.toString().toDouble()) | |
} | |
startActivity(context, bundle, context.packageName, clz.name, getOptionsBundle(context, enterAnim, exitAnim)) | |
} | |
private fun getOptionsBundle(context: Context, enterAnim: Int, exitAnim: Int): Bundle? = ActivityOptionsCompat.makeCustomAnimation(context, enterAnim, exitAnim).toBundle() | |
private fun startActivity(context: Context, extras: Bundle?, pkg: String, cls: String, options: Bundle?) { | |
val intent = Intent(Intent.ACTION_VIEW) | |
if (extras != null) intent.putExtras(extras) | |
intent.component = ComponentName(pkg, cls) | |
if (context !is Activity) intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) | |
if (options != null) context.startActivity(intent, options) | |
else context.startActivity(intent) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Barrow from AndroidUtilCode from BlankJ | |
* https://github.com/Blankj/AndroidUtilCode | |
*/ | |
package com.developersian.util.Utilities; | |
import android.annotation.*; | |
import android.app.*; | |
import android.app.Application.*; | |
import android.content.*; | |
import android.os.*; | |
import com.blankj.utilcode.util.*; | |
import java.lang.reflect.*; | |
import java.util.*; | |
public final class Toolkit{ | |
private static final ActivityLifecycleImpl ACTIVITY_LIFECYCLE=new ActivityLifecycleImpl(); | |
@SuppressLint("StaticFieldLeak") private static Application application; | |
private Toolkit(){ | |
throw new UnsupportedOperationException("u can't instantiate me..."); | |
} | |
private static void init(final Application app){ | |
if(application==null){ | |
if(app==null) | |
application=getApplicationByReflect(); | |
else | |
application=app; | |
application.registerActivityLifecycleCallbacks(ACTIVITY_LIFECYCLE); | |
} | |
} | |
private static Application getApp(){ | |
if(application!=null) | |
return application; | |
Application app=getApplicationByReflect(); | |
init(app); | |
return app; | |
} | |
private static Application getApplicationByReflect(){ | |
try{ | |
@SuppressLint("PrivateApi") Class<?> activityThread=Class.forName("android.app.ActivityThread"); | |
Object thread=activityThread.getMethod("currentActivityThread").invoke(null); | |
Object app=activityThread.getMethod("getApplication").invoke(thread); | |
if(app==null){ | |
throw new NullPointerException("u should init first"); | |
} | |
return (Application)app; | |
}catch(NoSuchMethodException|IllegalAccessException|ClassNotFoundException|InvocationTargetException e){ | |
e.printStackTrace(); | |
} | |
throw new NullPointerException("u should init first"); | |
} | |
public static Context getTopActivityOrApp(){ | |
if(isAppForeground()){ | |
Activity topActivity=ACTIVITY_LIFECYCLE.getTopActivity(); | |
return topActivity==null?Toolkit.getApp():topActivity; | |
}else{ | |
return Toolkit.getApp(); | |
} | |
} | |
private static boolean isAppForeground(){ | |
ActivityManager am=(ActivityManager)Toolkit.getApp().getSystemService(Context.ACTIVITY_SERVICE); | |
List<ActivityManager.RunningAppProcessInfo> info=am.getRunningAppProcesses(); | |
if(info==null||info.size()==0) | |
return false; | |
for(ActivityManager.RunningAppProcessInfo aInfo: info){ | |
if(aInfo.importance==ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND){ | |
return aInfo.processName.equals(Toolkit.getApp().getPackageName()); | |
} | |
} | |
return false; | |
} | |
public interface OnAppStatusChangedListener{ | |
void onForeground(); | |
void onBackground(); | |
} | |
static class ActivityLifecycleImpl implements ActivityLifecycleCallbacks{ | |
final LinkedList<Activity> activityList=new LinkedList<>(); | |
final HashMap<Object,OnAppStatusChangedListener> mStatusListenerMap=new HashMap<>(); | |
private int mForegroundCount=0; | |
private int mConfigCount=0; | |
@Override public void onActivityCreated(Activity activity,Bundle savedInstanceState){ | |
setTopActivity(activity); | |
} | |
@Override public void onActivityStarted(Activity activity){ | |
setTopActivity(activity); | |
if(mForegroundCount<=0){ | |
postStatus(true); | |
} | |
if(mConfigCount<0){ | |
++mConfigCount; | |
}else{ | |
++mForegroundCount; | |
} | |
} | |
@Override public void onActivityResumed(Activity activity){ | |
setTopActivity(activity); | |
} | |
@Override public void onActivityPaused(Activity activity){ | |
} | |
@Override public void onActivityStopped(Activity activity){ | |
if(activity.isChangingConfigurations()){ | |
--mConfigCount; | |
}else{ | |
--mForegroundCount; | |
if(mForegroundCount<=0){ | |
postStatus(false); | |
} | |
} | |
} | |
@Override public void onActivitySaveInstanceState(Activity activity,Bundle outState){ | |
} | |
@Override public void onActivityDestroyed(Activity activity){ | |
activityList.remove(activity); | |
} | |
private void postStatus(final boolean isForeground){ | |
if(mStatusListenerMap.isEmpty()) | |
return; | |
for(OnAppStatusChangedListener onAppStatusChangedListener: mStatusListenerMap.values()){ | |
if(onAppStatusChangedListener==null) | |
return; | |
if(isForeground) | |
onAppStatusChangedListener.onForeground(); | |
else | |
onAppStatusChangedListener.onBackground(); | |
} | |
} | |
Activity getTopActivity(){ | |
if(!activityList.isEmpty()){ | |
final Activity topActivity=activityList.getLast(); | |
if(topActivity!=null) | |
return topActivity; | |
} | |
Activity topActivityByReflect=getTopActivityByReflect(); | |
if(topActivityByReflect!=null) | |
setTopActivity(topActivityByReflect); | |
return topActivityByReflect; | |
} | |
private void setTopActivity(final Activity activity){ | |
if(activity.getClass()==PermissionUtils.PermissionActivity.class) | |
return; | |
if(activityList.contains(activity)){ | |
if(!activityList.getLast().equals(activity)){ | |
activityList.remove(activity); | |
activityList.addLast(activity); | |
} | |
}else | |
activityList.addLast(activity); | |
} | |
private Activity getTopActivityByReflect(){ | |
try{ | |
@SuppressLint("PrivateApi") Class<?> activityThreadClass=Class.forName("android.app.ActivityThread"); | |
Object activityThread=activityThreadClass.getMethod("currentActivityThread").invoke(null); | |
Field activitiesField=activityThreadClass.getDeclaredField("activityList"); | |
activitiesField.setAccessible(true); | |
Map activities=(Map)activitiesField.get(activityThread); | |
if(activities==null) | |
return null; | |
for(Object activityRecord: activities.values()){ | |
Class activityRecordClass=activityRecord.getClass(); | |
Field pausedField=activityRecordClass.getDeclaredField("paused"); | |
pausedField.setAccessible(true); | |
if(!pausedField.getBoolean(activityRecord)){ | |
Field activityField=activityRecordClass.getDeclaredField("activity"); | |
activityField.setAccessible(true); | |
return (Activity)activityField.get(activityRecord); | |
} | |
} | |
}catch(ClassNotFoundException|IllegalAccessException|NoSuchMethodException|InvocationTargetException|NoSuchFieldException e){ | |
e.printStackTrace(); | |
} | |
return null; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment