Skip to content

Instantly share code, notes, and snippets.

@SinaMN75
Last active June 28, 2019 10:35
Show Gist options
  • Save SinaMN75/5ba5a45bb9cb814e8809b1d94a794f0f to your computer and use it in GitHub Desktop.
Save SinaMN75/5ba5a45bb9cb814e8809b1d94a794f0f to your computer and use it in GitHub Desktop.
Easily StartActivity and Pass data...
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)
}
}
/**
* 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