From 55f2e7b20a9e957fdc1c1c73085d201a5edfcb55 Mon Sep 17 00:00:00 2001 From: hyb1996 <946994919@qq.com> Date: Wed, 25 Apr 2018 15:53:04 +0800 Subject: [PATCH] fix(autojs): screen request activity memory leak fix(autojs): idStartsWith not working --- .../scriptdroid/tool/CrashHandler.java | 4 ++ .../LayoutHierarchyFloatyWindow.java | 18 ++--- autojs/src/main/AndroidManifest.xml | 2 +- .../main/java/com/stardust/autojs/AutoJs.java | 14 +--- .../autojs/codegeneration/CodeGenerator.java | 4 +- .../autojs/core/accessibility/UiSelector.java | 28 +++++++- .../ScreenCaptureRequestActivity.java | 41 +++++++----- .../{ => capture}/ScreenCaptureRequester.java | 2 +- .../image/{ => capture}/ScreenCapturer.java | 2 +- .../execution/ScriptExecuteActivity.java | 6 +- .../autojs/runtime/ScriptRuntime.java | 11 +-- .../stardust/autojs/runtime/api/Images.java | 4 +- .../stardust/automator/filter/IdFilter.java | 19 ++---- .../automator/filter/StringEqualsFilter.java | 10 +-- .../java/com/stardust/util/IntentExtras.java | 67 +++++++++++++------ 15 files changed, 129 insertions(+), 103 deletions(-) rename autojs/src/main/java/com/stardust/autojs/core/image/{ => capture}/ScreenCaptureRequestActivity.java (65%) rename autojs/src/main/java/com/stardust/autojs/core/image/{ => capture}/ScreenCaptureRequester.java (98%) rename autojs/src/main/java/com/stardust/autojs/core/image/{ => capture}/ScreenCapturer.java (99%) diff --git a/app/src/main/java/com/stardust/scriptdroid/tool/CrashHandler.java b/app/src/main/java/com/stardust/scriptdroid/tool/CrashHandler.java index bd32b44d..f104e6e4 100644 --- a/app/src/main/java/com/stardust/scriptdroid/tool/CrashHandler.java +++ b/app/src/main/java/com/stardust/scriptdroid/tool/CrashHandler.java @@ -42,7 +42,11 @@ public class CrashHandler implements UncaughtExceptionHandler { } AccessibilityService service = AccessibilityService.getInstance(); if (service != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + Log.d(TAG, "disable service: " + service); service.disableSelf(); + } else { + Log.d(TAG, "cannot disable service: " + service); + } if (BuildConfig.DEBUG) { mDefaultHandler.uncaughtException(thread, ex); diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/floating/layoutinspector/LayoutHierarchyFloatyWindow.java b/app/src/main/java/com/stardust/scriptdroid/ui/floating/layoutinspector/LayoutHierarchyFloatyWindow.java index c0c678ff..41f7e697 100644 --- a/app/src/main/java/com/stardust/scriptdroid/ui/floating/layoutinspector/LayoutHierarchyFloatyWindow.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/floating/layoutinspector/LayoutHierarchyFloatyWindow.java @@ -33,7 +33,6 @@ public class LayoutHierarchyFloatyWindow extends FullScreenFloatyWindow { private MaterialDialog mNodeInfoDialog; private BubblePopupMenu mBubblePopMenu; private NodeInfoView mNodeInfoView; - private NodeInfo mSelectedNodeInfo; private Context mContext; private NodeInfo mRootNode; private NodeInfo mSelectedNode; @@ -65,15 +64,12 @@ public class LayoutHierarchyFloatyWindow extends FullScreenFloatyWindow { mLayoutHierarchyView.setShowClickedNodeBounds(true); mLayoutHierarchyView.getBoundsPaint().setStrokeWidth(3); mLayoutHierarchyView.getBoundsPaint().setColor(0xFFD32F2F); - mLayoutHierarchyView.setOnItemLongClickListener(new LayoutHierarchyView.OnItemLongClickListener() { - @Override - public void onItemLongClick(View view, NodeInfo nodeInfo) { - mSelectedNodeInfo = nodeInfo; - ensureOperationPopMenu(); - if (mBubblePopMenu.getContentView().getMeasuredWidth() <= 0) - mBubblePopMenu.preMeasure(); - mBubblePopMenu.showAsDropDown(view, view.getWidth() / 2 - mBubblePopMenu.getContentView().getMeasuredWidth() / 2, 0); - } + mLayoutHierarchyView.setOnItemLongClickListener((view, nodeInfo) -> { + mSelectedNode = nodeInfo; + ensureOperationPopMenu(); + if (mBubblePopMenu.getContentView().getMeasuredWidth() <= 0) + mBubblePopMenu.preMeasure(); + mBubblePopMenu.showAsDropDown(view, view.getWidth() / 2 - mBubblePopMenu.getContentView().getMeasuredWidth() / 2, 0); }); mLayoutHierarchyView.setRootNode(mRootNode); if (mSelectedNode != null) @@ -116,7 +112,7 @@ public class LayoutHierarchyFloatyWindow extends FullScreenFloatyWindow { void showNodeInfo() { ensureNodeInfoDialog(); - mNodeInfoView.setNodeInfo(mSelectedNodeInfo); + mNodeInfoView.setNodeInfo(mSelectedNode); mNodeInfoDialog.show(); } diff --git a/autojs/src/main/AndroidManifest.xml b/autojs/src/main/AndroidManifest.xml index 3a3ba863..c303a483 100644 --- a/autojs/src/main/AndroidManifest.xml +++ b/autojs/src/main/AndroidManifest.xml @@ -18,7 +18,7 @@ diff --git a/autojs/src/main/java/com/stardust/autojs/AutoJs.java b/autojs/src/main/java/com/stardust/autojs/AutoJs.java index 65dd6779..c6fc77c1 100644 --- a/autojs/src/main/java/com/stardust/autojs/AutoJs.java +++ b/autojs/src/main/java/com/stardust/autojs/AutoJs.java @@ -3,11 +3,6 @@ package com.stardust.autojs; import android.app.Activity; import android.app.Application; import android.content.Context; -import android.content.Intent; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Paint; import android.os.Build; import android.os.Bundle; import android.support.annotation.Nullable; @@ -18,24 +13,20 @@ import com.stardust.app.SimpleActivityLifecycleCallbacks; import com.stardust.autojs.core.accessibility.AccessibilityBridge; import com.stardust.autojs.core.console.GlobalStardustConsole; import com.stardust.autojs.core.console.StardustConsole; -import com.stardust.autojs.core.image.ScreenCaptureRequestActivity; -import com.stardust.autojs.core.image.ScreenCaptureRequester; -import com.stardust.autojs.core.inputevent.InputEventObserver; +import com.stardust.autojs.core.image.capture.ScreenCaptureRequestActivity; +import com.stardust.autojs.core.image.capture.ScreenCaptureRequester; import com.stardust.autojs.core.record.accessibility.AccessibilityActionRecorder; import com.stardust.autojs.core.util.Shell; import com.stardust.autojs.engine.LoopBasedJavaScriptEngine; import com.stardust.autojs.engine.RootAutomatorEngine; -import com.stardust.autojs.engine.ScriptEngine; import com.stardust.autojs.engine.ScriptEngineManager; import com.stardust.autojs.runtime.ScriptRuntime; import com.stardust.autojs.runtime.accessibility.AccessibilityConfig; import com.stardust.autojs.runtime.api.AppUtils; import com.stardust.autojs.runtime.api.Console; -import com.stardust.autojs.runtime.exception.ScriptException; import com.stardust.autojs.script.AutoFileSource; import com.stardust.autojs.script.JavaScriptSource; import com.stardust.util.ScreenMetrics; -import com.stardust.util.Supplier; import com.stardust.util.UiHandler; import com.stardust.view.accessibility.AccessibilityInfoProvider; import com.stardust.view.accessibility.AccessibilityNotificationObserver; @@ -224,7 +215,6 @@ public abstract class AutoJs { private class ScreenCaptureRequesterImpl extends ScreenCaptureRequester.AbstractScreenCaptureRequester { - @Override public void setOnActivityResultCallback(Callback callback) { super.setOnActivityResultCallback((result, data) -> { diff --git a/autojs/src/main/java/com/stardust/autojs/codegeneration/CodeGenerator.java b/autojs/src/main/java/com/stardust/autojs/codegeneration/CodeGenerator.java index 4bcaab58..efbe5dfa 100644 --- a/autojs/src/main/java/com/stardust/autojs/codegeneration/CodeGenerator.java +++ b/autojs/src/main/java/com/stardust/autojs/codegeneration/CodeGenerator.java @@ -17,8 +17,8 @@ public class CodeGenerator { public static final int WAIT_FOR = 2; public static final int EXISTS = 3; - private ReadOnlyUiObject mRoot; - private ReadOnlyUiObject mTarget; + private final ReadOnlyUiObject mRoot; + private final ReadOnlyUiObject mTarget; private boolean mUsingId = true; private boolean mUsingDesc = true; private boolean mUsingText = true; diff --git a/autojs/src/main/java/com/stardust/autojs/core/accessibility/UiSelector.java b/autojs/src/main/java/com/stardust/autojs/core/accessibility/UiSelector.java index 6121f88f..0e535be6 100644 --- a/autojs/src/main/java/com/stardust/autojs/core/accessibility/UiSelector.java +++ b/autojs/src/main/java/com/stardust/autojs/core/accessibility/UiSelector.java @@ -13,7 +13,6 @@ import com.stardust.automator.UiGlobalSelector; import com.stardust.automator.UiObject; import com.stardust.automator.UiObjectCollection; import com.stardust.automator.filter.DfsFilter; -import com.stardust.util.DeveloperUtils; import com.stardust.view.accessibility.AccessibilityNodeInfoAllocator; import static android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS; @@ -208,6 +207,11 @@ public class UiSelector extends UiGlobalSelector { String fullId = mAccessibilityBridge.getInfoProvider().getLatestPackage() + ":id/" + id; return fullId.equals(nodeInfo.getViewIdResourceName()); } + + @Override + public String toString() { + return "id(\"" + id + "\")"; + } }); } else { super.id(id); @@ -215,6 +219,27 @@ public class UiSelector extends UiGlobalSelector { return this; } + @Override + public UiGlobalSelector idStartsWith(String prefix) { + if (!prefix.contains(":")) { + addFilter(new DfsFilter() { + @Override + protected boolean isIncluded(UiObject nodeInfo) { + String fullIdPrefix = mAccessibilityBridge.getInfoProvider().getLatestPackage() + ":id/" + prefix; + String id = nodeInfo.getViewIdResourceName(); + return id != null && id.startsWith(fullIdPrefix); + } + + @Override + public String toString() { + return "idStartsWith(\"" + prefix + "\")"; + } + }); + } else { + super.idStartsWith(prefix); + } + return this; + } private boolean performAction(int action, ActionArgument... arguments) { return untilFind().performAction(action, arguments); @@ -351,5 +376,4 @@ public class UiSelector extends UiGlobalSelector { new ActionArgument.IntActionArgument(ACTION_ARGUMENT_ROW_INT, row), new ActionArgument.IntActionArgument(ACTION_ARGUMENT_COLUMN_INT, column)); } - } diff --git a/autojs/src/main/java/com/stardust/autojs/core/image/ScreenCaptureRequestActivity.java b/autojs/src/main/java/com/stardust/autojs/core/image/capture/ScreenCaptureRequestActivity.java similarity index 65% rename from autojs/src/main/java/com/stardust/autojs/core/image/ScreenCaptureRequestActivity.java rename to autojs/src/main/java/com/stardust/autojs/core/image/capture/ScreenCaptureRequestActivity.java index 5ee73af0..103039bd 100644 --- a/autojs/src/main/java/com/stardust/autojs/core/image/ScreenCaptureRequestActivity.java +++ b/autojs/src/main/java/com/stardust/autojs/core/image/capture/ScreenCaptureRequestActivity.java @@ -1,4 +1,4 @@ -package com.stardust.autojs.core.image; +package com.stardust.autojs.core.image.capture; import android.app.Activity; import android.content.Context; @@ -9,6 +9,7 @@ import android.support.annotation.Nullable; import android.support.annotation.RequiresApi; import com.stardust.app.OnActivityResultDelegate; +import com.stardust.util.IntentExtras; /** * Created by Stardust on 2017/5/22. @@ -17,32 +18,41 @@ import com.stardust.app.OnActivityResultDelegate; @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) public class ScreenCaptureRequestActivity extends Activity { - - private static ScreenCaptureRequester.Callback sCallback; - - public static void request(Context context, ScreenCaptureRequester.Callback callback) { - if (sCallback != null) { - return; - } - sCallback = callback; - context.startActivity(new Intent(context, ScreenCaptureRequestActivity.class) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); - } - private OnActivityResultDelegate.Mediator mOnActivityResultDelegateMediator = new OnActivityResultDelegate.Mediator(); private ScreenCaptureRequester mScreenCaptureRequester; + private ScreenCaptureRequester.Callback mCallback; + + public static void request(Context context, ScreenCaptureRequester.Callback callback) { + Intent intent = new Intent(context, ScreenCaptureRequestActivity.class) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + IntentExtras.newExtras() + .put("callback", callback) + .putInIntent(intent); + context.startActivity(intent); + } @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); + IntentExtras extras = IntentExtras.fromIntentAndRelease(getIntent()); + if (extras == null) { + finish(); + return; + } + mCallback = extras.get("callback"); + if (mCallback == null) { + finish(); + return; + } mScreenCaptureRequester = new ScreenCaptureRequester.ActivityScreenCaptureRequester(mOnActivityResultDelegateMediator, this); - mScreenCaptureRequester.setOnActivityResultCallback(sCallback); + mScreenCaptureRequester.setOnActivityResultCallback(mCallback); mScreenCaptureRequester.request(); } @Override protected void onDestroy() { super.onDestroy(); + mCallback = null; if (mScreenCaptureRequester == null) return; mScreenCaptureRequester.cancel(); @@ -52,8 +62,7 @@ public class ScreenCaptureRequestActivity extends Activity { @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { mOnActivityResultDelegateMediator.onActivityResult(requestCode, resultCode, data); - sCallback = null; finish(); } -} +} \ No newline at end of file diff --git a/autojs/src/main/java/com/stardust/autojs/core/image/ScreenCaptureRequester.java b/autojs/src/main/java/com/stardust/autojs/core/image/capture/ScreenCaptureRequester.java similarity index 98% rename from autojs/src/main/java/com/stardust/autojs/core/image/ScreenCaptureRequester.java rename to autojs/src/main/java/com/stardust/autojs/core/image/capture/ScreenCaptureRequester.java index 828bb6f2..39e2741e 100644 --- a/autojs/src/main/java/com/stardust/autojs/core/image/ScreenCaptureRequester.java +++ b/autojs/src/main/java/com/stardust/autojs/core/image/capture/ScreenCaptureRequester.java @@ -1,4 +1,4 @@ -package com.stardust.autojs.core.image; +package com.stardust.autojs.core.image.capture; import android.app.Activity; import android.content.Context; diff --git a/autojs/src/main/java/com/stardust/autojs/core/image/ScreenCapturer.java b/autojs/src/main/java/com/stardust/autojs/core/image/capture/ScreenCapturer.java similarity index 99% rename from autojs/src/main/java/com/stardust/autojs/core/image/ScreenCapturer.java rename to autojs/src/main/java/com/stardust/autojs/core/image/capture/ScreenCapturer.java index d07dc1c5..91d3cc19 100644 --- a/autojs/src/main/java/com/stardust/autojs/core/image/ScreenCapturer.java +++ b/autojs/src/main/java/com/stardust/autojs/core/image/capture/ScreenCapturer.java @@ -1,4 +1,4 @@ -package com.stardust.autojs.core.image; +package com.stardust.autojs.core.image.capture; import android.app.Activity; import android.content.Context; diff --git a/autojs/src/main/java/com/stardust/autojs/execution/ScriptExecuteActivity.java b/autojs/src/main/java/com/stardust/autojs/execution/ScriptExecuteActivity.java index d5f2b938..6f68d0b2 100644 --- a/autojs/src/main/java/com/stardust/autojs/execution/ScriptExecuteActivity.java +++ b/autojs/src/main/java/com/stardust/autojs/execution/ScriptExecuteActivity.java @@ -7,10 +7,8 @@ import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import com.stardust.autojs.engine.LoopBasedJavaScriptEngine; -import com.stardust.autojs.engine.RhinoJavaScriptEngine; import com.stardust.autojs.engine.ScriptEngine; import com.stardust.autojs.engine.ScriptEngineManager; -import com.stardust.autojs.engine.ScriptEngineProxy; import com.stardust.autojs.script.ScriptSource; import com.stardust.util.IntentExtras; @@ -57,13 +55,13 @@ public class ScriptExecuteActivity extends AppCompatActivity { } private IntentExtras readIntentExtras(Bundle savedInstanceState) { - IntentExtras extras = IntentExtras.fromIntent(getIntent()); + IntentExtras extras = IntentExtras.fromIntentAndRelease(getIntent()); if (extras == null && savedInstanceState != null) { int id = savedInstanceState.getInt(IntentExtras.EXTRA_ID, -1); if (id == -1) { return null; } - extras = IntentExtras.fromId(id); + extras = IntentExtras.fromIdAndRelease(id); } return extras; } diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/ScriptRuntime.java b/autojs/src/main/java/com/stardust/autojs/runtime/ScriptRuntime.java index 8a22fabc..45ae14cb 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/ScriptRuntime.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/ScriptRuntime.java @@ -1,22 +1,15 @@ package com.stardust.autojs.runtime; import android.content.Context; -import android.content.pm.PackageManager; import android.os.Build; import android.os.Looper; -import android.view.MotionEvent; -import android.view.View; import com.stardust.app.GlobalAppContext; -import com.stardust.autojs.BuildConfig; import com.stardust.autojs.R; import com.stardust.autojs.ScriptEngineService; import com.stardust.autojs.annotation.ScriptVariable; import com.stardust.autojs.core.accessibility.AccessibilityBridge; import com.stardust.autojs.core.image.Colors; -import com.stardust.autojs.engine.JavaScriptEngine; -import com.stardust.autojs.engine.RhinoJavaScriptEngine; -import com.stardust.autojs.engine.ScriptEngine; import com.stardust.autojs.rhino.AndroidClassLoader; import com.stardust.autojs.runtime.api.AbstractShell; import com.stardust.autojs.runtime.api.AppUtils; @@ -33,7 +26,7 @@ import com.stardust.autojs.runtime.api.Threads; import com.stardust.autojs.runtime.api.Timers; import com.stardust.autojs.core.accessibility.UiSelector; import com.stardust.autojs.runtime.api.Images; -import com.stardust.autojs.core.image.ScreenCaptureRequester; +import com.stardust.autojs.core.image.capture.ScreenCaptureRequester; import com.stardust.autojs.runtime.api.Dialogs; import com.stardust.autojs.runtime.exception.ScriptEnvironmentException; import com.stardust.autojs.runtime.exception.ScriptException; @@ -59,8 +52,6 @@ import java.lang.ref.WeakReference; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import javax.microedition.khronos.opengles.GL; - /** * Created by Stardust on 2017/1/27. diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/api/Images.java b/autojs/src/main/java/com/stardust/autojs/runtime/api/Images.java index 8ace7670..b5993c6c 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/api/Images.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/api/Images.java @@ -18,8 +18,8 @@ import com.stardust.autojs.annotation.ScriptVariable; import com.stardust.autojs.core.image.ColorFinder; import com.stardust.autojs.core.image.ImageWrapper; import com.stardust.autojs.core.image.OpenCVHelper; -import com.stardust.autojs.core.image.ScreenCaptureRequester; -import com.stardust.autojs.core.image.ScreenCapturer; +import com.stardust.autojs.core.image.capture.ScreenCaptureRequester; +import com.stardust.autojs.core.image.capture.ScreenCapturer; import com.stardust.autojs.core.image.TemplateMatching; import com.stardust.autojs.core.ui.inflater.util.Drawables; import com.stardust.autojs.runtime.ScriptRuntime; diff --git a/automator/src/main/java/com/stardust/automator/filter/IdFilter.java b/automator/src/main/java/com/stardust/automator/filter/IdFilter.java index 917129fa..36f67f5f 100644 --- a/automator/src/main/java/com/stardust/automator/filter/IdFilter.java +++ b/automator/src/main/java/com/stardust/automator/filter/IdFilter.java @@ -8,7 +8,11 @@ import java.util.List; * Created by Stardust on 2017/3/9. */ -public class IdFilter extends ListFilter.Default { +public class IdFilter { + + public interface FullIdGetter { + String getFullId(String id); + } private static final KeyGetter ID_GETTER = new KeyGetter() { @@ -26,7 +30,6 @@ public class IdFilter extends ListFilter.Default { public static StringEqualsFilter equals(String id) { return new StringEqualsFilter(id, ID_GETTER); } - public static StringStartsWithFilter startsWith(String prefix) { return new StringStartsWithFilter(prefix, ID_GETTER); } @@ -43,16 +46,4 @@ public class IdFilter extends ListFilter.Default { return new StringMatchesFilter(regex, ID_GETTER); } - private String mId; - - private IdFilter(String id) { - mId = id; - } - - @Override - public List filter(UiObject node) { - return node.findByViewId(mId); - } - - } diff --git a/automator/src/main/java/com/stardust/automator/filter/StringEqualsFilter.java b/automator/src/main/java/com/stardust/automator/filter/StringEqualsFilter.java index 61059ffe..27ff9168 100644 --- a/automator/src/main/java/com/stardust/automator/filter/StringEqualsFilter.java +++ b/automator/src/main/java/com/stardust/automator/filter/StringEqualsFilter.java @@ -8,11 +8,11 @@ import com.stardust.automator.UiObject; public class StringEqualsFilter extends DfsFilter { - private String mText; + private String mValue; private KeyGetter mKeyGetter; - public StringEqualsFilter(String text, KeyGetter getter) { - mText = text; + public StringEqualsFilter(String value, KeyGetter getter) { + mValue = value; mKeyGetter = getter; } @@ -20,13 +20,13 @@ public class StringEqualsFilter extends DfsFilter { protected boolean isIncluded(UiObject nodeInfo) { String key = mKeyGetter.getKey(nodeInfo); if (key != null) { - return key.equals(mText); + return key.equals(mValue); } return false; } @Override public String toString() { - return mKeyGetter.toString() + "(\"" + mText + "\")"; + return mKeyGetter.toString() + "(\"" + mValue + "\")"; } } diff --git a/common/src/main/java/com/stardust/util/IntentExtras.java b/common/src/main/java/com/stardust/util/IntentExtras.java index 5c680857..2d078468 100644 --- a/common/src/main/java/com/stardust/util/IntentExtras.java +++ b/common/src/main/java/com/stardust/util/IntentExtras.java @@ -19,28 +19,6 @@ public class IntentExtras implements Serializable { private static AtomicInteger mMaxId = new AtomicInteger(-1); private static SparseArray> extraStore = new SparseArray<>(); - - public static IntentExtras newExtras() { - return new IntentExtras(); - } - - public static IntentExtras fromIntent(Intent intent) { - int id = intent.getIntExtra(EXTRA_ID, -1); - if (id < 0) { - return null; - } - return fromId(id); - } - - public static IntentExtras fromId(int id) { - Map map = extraStore.get(id); - if (map == null) { - return null; - } - extraStore.remove(id); - return new IntentExtras(id, map); - } - private Map mMap; private int mId; @@ -56,6 +34,46 @@ public class IntentExtras implements Serializable { mMap = map; } + + public static IntentExtras newExtras() { + return new IntentExtras(); + } + + public static IntentExtras fromIntentAndRelease(Intent intent) { + int id = intent.getIntExtra(EXTRA_ID, -1); + if (id < 0) { + return null; + } + return fromIdAndRelease(id); + } + + public static IntentExtras fromIdAndRelease(int id) { + Map map = extraStore.get(id); + if (map == null) { + return null; + } + extraStore.remove(id); + return new IntentExtras(id, map); + } + + public static IntentExtras fromId(int id) { + Map map = extraStore.get(id); + if (map == null) { + return null; + } + return new IntentExtras(id, map); + } + + + public static IntentExtras fromIntent(Intent intent) { + int id = intent.getIntExtra(EXTRA_ID, -1); + if (id < 0) { + return null; + } + return fromId(id); + } + + public int getId() { return mId; } @@ -80,5 +98,10 @@ public class IntentExtras implements Serializable { return intent; } + public void release() { + extraStore.remove(mId); + mId = -1; + } + }