下面列出了怎么用androidx.annotation.Keep的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* Instrumentation的newActivity方法,用类加载器来创建Activity实例
* 还原目标Activity.
*/
@Keep
@Override
public Activity newActivity(ClassLoader classLoader, String className, Intent intent) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
Intent pluginIntent = intent.getParcelableExtra(TARGET_INTENT_CLASS);
boolean pluginIntentClassNameExist = pluginIntent != null && !TextUtils.isEmpty(pluginIntent.getComponent().getClassName());
//1.className
String finalClassName = pluginIntentClassNameExist ? pluginIntent.getComponent().getClassName() : className;
//2.intent
Intent finalIntent = pluginIntentClassNameExist ? pluginIntent : intent;
//3.classLoader
File pluginDexFile = MApplication.getInstance().getFileStreamPath(PluginApkNameVersion.PLUGIN_ACTIVITY_APK);
ClassLoader finalClassLoader = pluginIntentClassNameExist ? CustomClassLoader.getPluginClassLoader(pluginDexFile, "com.malin.plugin") : classLoader;
if (Build.VERSION.SDK_INT >= 28) {
return mInstrumentation.newActivity(finalClassLoader, finalClassName, finalIntent);
}
return super.newActivity(finalClassLoader, finalClassName, finalIntent);
}
@Keep
public BaldKeyboard(final Context context, final View.OnClickListener onClickListener, final Runnable backspaceRunnable, final int imeOptions) {
super(context);
vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
this.backspaceRunnable = backspaceRunnable;
final ContextThemeWrapper contextThemeWrapper = new ContextThemeWrapper(context, S.getTheme(context));
keyboard = (ConstraintLayout) LayoutInflater.from(contextThemeWrapper).inflate(layout(), this, false);
children = new View[keyboard.getChildCount()];
final char[] codes = codes();
for (int i = 0; i < children.length - 1/*cause of space view...*/; i++) {
final View view = keyboard.getChildAt(i + 1/*cause of space view...*/);
view.setOnClickListener(onClickListener);
view.setTag(codes[i]);
children[i] = view;
}
backspace = keyboard.findViewById(R.id.backspace);
backspace.setOnTouchListener(getBackSpaceListener());
enter = keyboard.findViewById(R.id.enter);
tv_enter = keyboard.findViewById(R.id.tv_enter);
iv_enter = keyboard.findViewById(R.id.iv_enter);
imeOptionsChanged(imeOptions);
addView(keyboard);
}
@Override
@Keep
public List<Component<?>> getComponents() {
return Arrays.asList(
Component.builder(FirestoreMultiDbComponent.class)
.add(Dependency.required(FirebaseApp.class))
.add(Dependency.required(Context.class))
.add(Dependency.optionalProvider(HeartBeatInfo.class))
.add(Dependency.optionalProvider(UserAgentPublisher.class))
.add(Dependency.optional(InternalAuthProvider.class))
.factory(
c ->
new FirestoreMultiDbComponent(
c.get(Context.class),
c.get(FirebaseApp.class),
c.get(InternalAuthProvider.class),
new FirebaseClientGrpcMetadataProvider(
c.getProvider(UserAgentPublisher.class),
c.getProvider(HeartBeatInfo.class))))
.build(),
LibraryVersionComponent.create("fire-fst", BuildConfig.VERSION_NAME));
}
@Keep
@SuppressWarnings("unused")
void handleMotionEvent(final int aHandle, final int aDevice, final boolean aFocused, final boolean aPressed, final float aX, final float aY) {
runOnUiThread(() -> {
Widget widget = mWidgets.get(aHandle);
if (!isWidgetInputEnabled(widget)) {
widget = null; // Fallback to mRootWidget in order to allow world clicks to dismiss UI.
}
float scale = widget != null ? widget.getPlacement().textureScale : 1.0f;
final float x = aX / scale;
final float y = aY / scale;
if (widget == null) {
MotionEventGenerator.dispatch(mRootWidget, aDevice, aFocused, aPressed, x, y);
} else if (widget.getBorderWidth() > 0) {
final int border = widget.getBorderWidth();
MotionEventGenerator.dispatch(widget, aDevice, aFocused, aPressed, x - border, y - border);
} else {
MotionEventGenerator.dispatch(widget, aDevice, aFocused, aPressed, x, y);
}
});
}
@Keep
@SuppressWarnings("unused")
void handleScrollEvent(final int aHandle, final int aDevice, final float aX, final float aY) {
runOnUiThread(() -> {
Widget widget = mWidgets.get(aHandle);
if (!isWidgetInputEnabled(widget)) {
return;
}
if (widget != null) {
float scrollDirection = mSettings.getScrollDirection() == 0 ? 1.0f : -1.0f;
MotionEventGenerator.dispatchScroll(widget, aDevice, true,aX * scrollDirection, aY * scrollDirection);
} else {
Log.e(LOGTAG, "Failed to find widget for scroll event: " + aHandle);
}
});
}
@Keep
public SOAEntry(JSONObject obj) throws JSONException {
super(obj);
mname = obj.getString("mname");
rname = obj.getString("rname");
serial = obj.getInt("serial");
refresh = obj.getInt("refresh");
retry = obj.getInt("retry");
expire = obj.getInt("expire");
minimum_ttl = obj.getInt("minimum-ttl");
}
@Override
@Keep
public List<Component<?>> getComponents() {
Component<FirebaseDynamicLinks> firebaseDynamicLinks =
Component.builder(FirebaseDynamicLinks.class)
.add(Dependency.required(FirebaseApp.class))
.add(Dependency.optional(AnalyticsConnector.class))
.factory(
container ->
new FirebaseDynamicLinksImpl(
container.get(FirebaseApp.class), container.get(AnalyticsConnector.class)))
.build(); // no need for eager init for the Internal component.
return Collections.singletonList(firebaseDynamicLinks);
}
@Override
@Keep
public List<Component<?>> getComponents() {
return Arrays.asList(
Component.builder(FirebaseInAppMessagingDisplay.class)
.add(Dependency.required(FirebaseApp.class))
.add(Dependency.required(AnalyticsConnector.class))
.add(Dependency.required(FirebaseInAppMessaging.class))
.factory(this::buildFirebaseInAppMessagingUI)
.eagerInDefaultApp()
.build(),
LibraryVersionComponent.create("fire-fiamd", BuildConfig.VERSION_NAME));
}
@Keep
@SuppressWarnings("unused")
private void cancelAllHaptics() {
runOnUiThread(() -> {
if (mControllerManager != null) {
ControllerClient.vibrateCV2ControllerStrength(0, 0, 0);
ControllerClient.vibrateCV2ControllerStrength(0, 0, 1);
}
});
}
@Keep
@SuppressWarnings("unused")
void handleGesture(final int aType) {
runOnUiThread(() -> {
boolean consumed = false;
if ((aType == GestureSwipeLeft) && (mLastGesture == GestureSwipeLeft)) {
Log.d(LOGTAG, "Go back!");
SessionStore.get().getActiveSession().goBack();
consumed = true;
} else if ((aType == GestureSwipeRight) && (mLastGesture == GestureSwipeRight)) {
Log.d(LOGTAG, "Go forward!");
SessionStore.get().getActiveSession().goForward();
consumed = true;
}
if (mLastRunnable != null) {
mLastRunnable.mCanceled = true;
mLastRunnable = null;
}
if (consumed) {
mLastGesture = NoGesture;
} else {
mLastGesture = aType;
mLastRunnable = new SwipeRunnable();
mHandler.postDelayed(mLastRunnable, SwipeDelay);
}
});
}
@SuppressWarnings({"UnusedDeclaration"})
@Keep
void handleBack() {
runOnUiThread(() -> {
// On WAVE VR, the back button no longer seems to work.
if (DeviceType.isWaveBuild()) {
onBackPressed();
return;
}
dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK));
dispatchKeyEvent(new KeyEvent (KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK));
});
}
@Keep
@SuppressWarnings("unused")
void handleMoveEnd(final int aHandle, final float aDeltaX, final float aDeltaY, final float aDeltaZ, final float aRotation) {
runOnUiThread(() -> {
Widget widget = mWidgets.get(aHandle);
if (widget != null) {
widget.handleMoveEvent(aDeltaX, aDeltaY, aDeltaZ, aRotation);
}
});
}
@Keep
@SuppressWarnings("unused")
void onEnterWebXR() {
if (Thread.currentThread() == mUiThread) {
return;
}
mIsPresentingImmersive = true;
runOnUiThread(() -> {
mWindows.enterImmersiveMode();
for (WebXRListener listener: mWebXRListeners) {
listener.onEnterWebXR();
}
});
TelemetryWrapper.startImmersive();
GleanMetricsService.startImmersive();
PauseCompositorRunnable runnable = new PauseCompositorRunnable();
synchronized (mCompositorLock) {
runOnUiThread(runnable);
while (!runnable.done) {
try {
mCompositorLock.wait();
} catch (InterruptedException e) {
Log.e(LOGTAG, "Waiting for compositor pause interrupted");
}
}
}
}
@Keep
@SuppressWarnings("unused")
void onDismissWebXRInterstitial() {
runOnUiThread(() -> {
for (WebXRListener listener: mWebXRListeners) {
listener.onDismissWebXRInterstitial();
}
});
}
@Keep
@SuppressWarnings("unused")
void renderPointerLayer(final Surface aSurface, final long aNativeCallback) {
runOnUiThread(() -> {
try {
Canvas canvas = aSurface.lockHardwareCanvas();
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setDither(true);
paint.setColor(Color.WHITE);
paint.setStyle(Paint.Style.FILL);
final float x = canvas.getWidth() * 0.5f;
final float y = canvas.getHeight() * 0.5f;
final float radius = canvas.getWidth() * 0.4f;
canvas.drawCircle(x, y, radius, paint);
paint.setColor(Color.BLACK);
paint.setStrokeWidth(4);
paint.setStyle(Paint.Style.STROKE);
canvas.drawCircle(x, y, radius, paint);
aSurface.unlockCanvasAndPost(canvas);
}
catch (Exception ex) {
ex.printStackTrace();
}
if (aNativeCallback != 0) {
queueRunnable(() -> runCallbackNative(aNativeCallback));
}
});
}
@Keep
@SuppressWarnings("unused")
String getStorageAbsolutePath() {
final File path = getExternalFilesDir(null);
if (path == null) {
return "";
}
return path.getAbsolutePath();
}
@Keep
@SuppressWarnings("unused")
private void setDeviceType(int aType) {
if (DeviceType.isOculusBuild() || DeviceType.isWaveBuild()) {
runOnUiThread(() -> DeviceType.setType(aType));
}
}
@Keep
public void setValue(int value) {
this.value = value;
if (this.value > max)
this.value = max;
if (this.value < min)
this.value = min;
if (listener != null) listener.onValueChanged(this.value);
invalidate();
}
@Keep
private void ownBitmap(Bitmap bitmap, int left, int top) {
if (mBitmap != null && !mBitmap.isRecycled()) {
mBitmap.recycle();
}
mBitmap = bitmap;
mLeftSideBearing = left;
mTopSideBearing = top;
}
/**
* @return the {@link LithoView} associated with this ComponentTree if any. Since this is modified
* on the main thread, it is racy to get the current LithoView off the main thread.
*/
@Keep
@Nullable
@UiThread
public LithoView getLithoView() {
return mLithoView;
}
@Keep
public void setValue(int value) {
mData2.int1 = value;
mData2.int2 = value;
mDataReflOtherName.int1 = value;
mDataReflOtherName.int2 = value;
}
@Keep
public void verifyValue(int value) {
if (mData2.int1 != value) {
throw new IllegalStateException();
}
if (mData2.int2 != value) {
throw new IllegalStateException();
}
if (mDataReflOtherName.int1 != value) {
throw new IllegalStateException();
}
if (mDataReflOtherName.int2 != value) {
throw new IllegalStateException();
}
}
/**
* monitor stop work
*/
@Keep
static synchronized void shutDown() {
if (sGodEyeMonitorServer != null) {
sGodEyeMonitorServer.stop();
sGodEyeMonitorServer = null;
}
ModuleDriver.instance().stop();
NotificationObserverManager.uninstallNotificationListener("MONITOR");
sIsWorking = false;
L.d("GodEye monitor stopped.");
}
@Keep
public static void install(final Application application, final Leak leakModule) {
ThreadUtil.sMain.execute(new Runnable() {
@Override
public void run() {
AppWatcher.INSTANCE.manualInstall(application);
LeakCanary.INSTANCE.showLeakDisplayActivityLauncherIcon(false);
LeakCanary.setConfig(new LeakCanary.Config().newBuilder()
.requestWriteExternalStoragePermission(false)
.dumpHeap(true)
.onHeapAnalyzedListener(new OnHeapAnalyzedListener() {
@Override
public void onHeapAnalyzed(@NotNull HeapAnalysis heapAnalysis) {
if (heapAnalysis instanceof HeapAnalysisFailure) {
L.w("GodEyePluginLeakCanary leak analysis failure:" + heapAnalysis.toString());
return;
}
if (!(heapAnalysis instanceof HeapAnalysisSuccess)) {
L.w("GodEyePluginLeakCanary leak analysis type error: " + heapAnalysis.getClass().getName());
return;
}
final HeapAnalysisSuccess analysisSuccess = (HeapAnalysisSuccess) heapAnalysis;
IteratorUtil.forEach(analysisSuccess.getAllLeaks().iterator(), new Consumer<shark.Leak>() {
@Override
public void accept(shark.Leak leak) {
leakModule.produce(new LeakInfo(analysisSuccess.getCreatedAtTimeMillis(), analysisSuccess.getAnalysisDurationMillis(), leak));
}
});
}
}).build());
AppWatcher.setConfig(new AppWatcher.Config().newBuilder().enabled(true).build());
}
});
}
@Keep
public static void uninstall() {
ThreadUtil.sMain.execute(new Runnable() {
@Override
public void run() {
AppWatcher.setConfig(new AppWatcher.Config().newBuilder().enabled(false).build());
}
});
}
/**
* Opens the settings page for configuring Taskbar, using the specified title and theme.
* @param context Context used to start the activity
* @param title Title to display in the top level of the settings hierarchy.
* If null, defaults to "Settings".
* @param theme Theme to apply to the settings activity. If set to -1, the activity will
* use the app's default theme if it is a derivative of Theme.AppCompat,
* or Theme.AppCompat.Light otherwise.
*/
@Keep public static void openSettings(@NonNull Context context, @Nullable String title, @StyleRes int theme) {
Intent intent = new Intent(context, MainActivity.class);
intent.putExtra("title", title);
intent.putExtra("theme", theme);
intent.putExtra("back_arrow", true);
if(!(context instanceof Activity))
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
@JavascriptInterface
@Keep
public final void startPage(String url) {
if (!hasAccessPermission()) {
return;
}
GRouter.getInstance().startActivity(this.activity, url);
}
@Keep
public void setAlpha(float alpha) {
delegateView.setAlpha(alpha);
}
/**
* Controls logging of debug messages. All instances are affected.
* @param debug true to enable debug logging, false to disable.
*/
@Keep
@SuppressWarnings("unused")
public static void setDebug(boolean debug) {
SkiaPooledImageRegionDecoder.debug = debug;
}
@Keep
@SuppressWarnings("unused")
public SkiaImageRegionDecoder() {
this(null);
}