下面列出了怎么用android.app.ActivityThread的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* @see #requestSync(Account, String, Bundle)
* @hide
*/
public static void requestSyncAsUser(Account account, String authority, @UserIdInt int userId,
Bundle extras) {
if (extras == null) {
throw new IllegalArgumentException("Must specify extras.");
}
SyncRequest request =
new SyncRequest.Builder()
.setSyncAdapter(account, authority)
.setExtras(extras)
.syncOnce() // Immediate sync.
.build();
try {
// Note ActivityThread.currentPackageName() may not be accurate in a shared process
// case, but it's only for debugging.
getContentService().syncAsUser(request, userId, ActivityThread.currentPackageName());
} catch(RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
public void updateSystemUiContext() {
if (mInitCompleteSignal != null) {
ConcurrentUtils.waitForFutureNoInterrupt(mInitCompleteSignal,
"Wait for OverlayManagerService init");
mInitCompleteSignal = null;
}
final ApplicationInfo ai;
try {
ai = mPackageManager.mPackageManager.getApplicationInfo("android",
GET_SHARED_LIBRARY_FILES, UserHandle.USER_SYSTEM);
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
ActivityThread.currentActivityThread().handleSystemApplicationInfoChanged(ai);
}
@Override
public void uncaughtException(Thread t, Throwable e) {
mTriggered = true;
// Don't re-enter if KillApplicationHandler has already run
if (mCrashing) return;
// mApplicationObject is null for non-zygote java programs (e.g. "am")
// There are also apps running with the system UID. We don't want the
// first clause in either of these two cases, only for system_server.
if (mApplicationObject == null && (Process.SYSTEM_UID == Process.myUid())) {
Clog_e(TAG, "*** FATAL EXCEPTION IN SYSTEM PROCESS: " + t.getName(), e);
} else {
StringBuilder message = new StringBuilder();
// The "FATAL EXCEPTION" string is still used on Android even though
// apps can set a custom UncaughtExceptionHandler that renders uncaught
// exceptions non-fatal.
message.append("FATAL EXCEPTION: ").append(t.getName()).append("\n");
final String processName = ActivityThread.currentProcessName();
if (processName != null) {
message.append("Process: ").append(processName).append(", ");
}
message.append("PID: ").append(Process.myPid());
Clog_e(TAG, message.toString(), e);
}
}
public AnimatorSet() {
super();
mNodeMap.put(mDelayAnim, mRootNode);
mNodes.add(mRootNode);
boolean isPreO;
// Set the flag to ignore calling end() without start() for pre-N releases
Application app = ActivityThread.currentApplication();
if (app == null || app.getApplicationInfo() == null) {
mShouldIgnoreEndWithoutStart = true;
isPreO = true;
} else {
if (app.getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.N) {
mShouldIgnoreEndWithoutStart = true;
} else {
mShouldIgnoreEndWithoutStart = false;
}
isPreO = app.getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.O;
}
mShouldResetValuesAtStart = !isPreO;
mEndCanBeCalled = !isPreO;
}
/**
* Turns off Bluetooth LE which was earlier turned on by calling enableBLE().
*
* <p> If the internal Adapter state is STATE_BLE_ON, this would trigger the transition
* to STATE_OFF and completely shut-down Bluetooth
*
* <p> If the Adapter state is STATE_ON, This would unregister the existance of
* special Bluetooth LE application and hence the further turning off of Bluetooth
* from UI would ensure the complete turn-off of Bluetooth rather than staying back
* BLE only state
*
* <p>This is an asynchronous call: it will return immediately, and
* clients should listen for {@link #ACTION_BLE_STATE_CHANGED}
* to be notified of subsequent adapter state changes If this call returns
* true, then the adapter state will immediately transition from {@link
* #STATE_ON} to {@link #STATE_TURNING_OFF}, and some time
* later transition to either {@link #STATE_BLE_ON} or {@link
* #STATE_OFF} based on the existance of the further Always BLE ON enabled applications
* If this call returns false then there was an
* immediate problem that will prevent the QAdapter from being turned off -
* such as the QAadapter already being turned off.
*
* @return true to indicate success, or false on immediate error
* @hide
*/
@SystemApi
public boolean disableBLE() {
if (!isBleScanAlwaysAvailable()) {
return false;
}
int state = getLeState();
if (state == BluetoothAdapter.STATE_ON || state == BluetoothAdapter.STATE_BLE_ON) {
String packageName = ActivityThread.currentPackageName();
if (DBG) {
Log.d(TAG, "disableBLE(): de-registering " + packageName);
}
try {
mManagerService.updateBleAppCount(mToken, false, packageName);
} catch (RemoteException e) {
Log.e(TAG, "", e);
}
return true;
}
if (DBG) {
Log.d(TAG, "disableBLE(): Already disabled");
}
return false;
}
/**
* Enable the Bluetooth Adapter, but don't auto-connect devices
* and don't persist state. Only for use by system applications.
*
* @hide
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN)
public boolean enableNoAutoConnect() {
if (isEnabled()) {
if (DBG) {
Log.d(TAG, "enableNoAutoConnect(): BT already enabled!");
}
return true;
}
try {
return mManagerService.enableNoAutoConnect(ActivityThread.currentPackageName());
} catch (RemoteException e) {
Log.e(TAG, "", e);
}
return false;
}
private static void initIfNeeded() {
if (sInitialized || sCallingGlobalSettings) {
return;
}
ActivityThread activityThread = ActivityThread.currentActivityThread();
Application app = activityThread == null ? null : activityThread.getApplication();
String flags = null;
if (app == null) {
Log.w(TAG, "Cannot read global setting "
+ Settings.Global.SQLITE_COMPATIBILITY_WAL_FLAGS + " - "
+ "Application state not available");
} else {
try {
sCallingGlobalSettings = true;
flags = Settings.Global.getString(app.getContentResolver(),
Settings.Global.SQLITE_COMPATIBILITY_WAL_FLAGS);
} finally {
sCallingGlobalSettings = false;
}
}
init(flags);
}
private int cameraInitVersion(int cameraId, int halVersion) {
mShutterCallback = null;
mRawImageCallback = null;
mJpegCallback = null;
mPreviewCallback = null;
mPostviewCallback = null;
mUsingPreviewAllocation = false;
mZoomListener = null;
Looper looper;
if ((looper = Looper.myLooper()) != null) {
mEventHandler = new EventHandler(this, looper);
} else if ((looper = Looper.getMainLooper()) != null) {
mEventHandler = new EventHandler(this, looper);
} else {
mEventHandler = null;
}
return native_setup(new WeakReference<Camera>(this), cameraId, halVersion,
ActivityThread.currentOpPackageName());
}
private static ApplicationInfo getApplicationInfo(String packageName, int userId) {
if (packageName == null) {
return null;
}
// Get the application for the passed in package and user.
Application application = ActivityThread.currentApplication();
if (application == null) {
throw new IllegalStateException("Cannot create remote views out of an aplication.");
}
ApplicationInfo applicationInfo = application.getApplicationInfo();
if (UserHandle.getUserId(applicationInfo.uid) != userId
|| !applicationInfo.packageName.equals(packageName)) {
try {
Context context = application.getBaseContext().createPackageContextAsUser(
packageName, 0, new UserHandle(userId));
applicationInfo = context.getApplicationInfo();
} catch (NameNotFoundException nnfe) {
throw new IllegalArgumentException("No such package " + packageName);
}
}
return applicationInfo;
}
public static void hookResources(Context base, Resources resources) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
return;
}
try {
Reflector reflector = Reflector.with(base);
reflector.field("mResources").set(resources);
Object loadedApk = reflector.field("mPackageInfo").get();
Reflector.with(loadedApk).field("mResources").set(resources);
Object activityThread = ActivityThread.currentActivityThread();
Object resManager;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
resManager = android.app.ResourcesManager.getInstance();
} else {
resManager = Reflector.with(activityThread).field("mResourcesManager").get();
}
Map<Object, WeakReference<Resources>> map = Reflector.with(resManager).field("mActiveResources").get();
Object key = map.keySet().iterator().next();
map.put(key, new WeakReference<>(resources));
} catch (Exception e) {
Log.w(TAG, e);
}
}
protected PluginManager(Context context) {
if (context instanceof Application) {
this.mApplication = (Application) context;
this.mContext = mApplication.getBaseContext();
} else {
final Context app = context.getApplicationContext();
if (app == null) {
this.mContext = context;
this.mApplication = ActivityThread.currentApplication();
} else {
this.mApplication = (Application) app;
this.mContext = mApplication.getBaseContext();
}
}
mComponentsHandler = createComponentsHandler();
hookCurrentProcess();
}
protected void hookInstrumentationAndHandler() {
try {
ActivityThread activityThread = ActivityThread.currentActivityThread();
Instrumentation baseInstrumentation = activityThread.getInstrumentation();
// if (baseInstrumentation.getClass().getName().contains("lbe")) {
// // reject executing in paralell space, for example, lbe.
// System.exit(0);
// }
final VAInstrumentation instrumentation = createInstrumentation(baseInstrumentation);
Reflector.with(activityThread).field("mInstrumentation").set(instrumentation);
Handler mainHandler = Reflector.with(activityThread).method("getHandler").call();
Reflector.with(mainHandler).field("mCallback").set(instrumentation);
this.mInstrumentation = instrumentation;
Log.d(TAG, "hookInstrumentationAndHandler succeed : " + mInstrumentation);
} catch (Exception e) {
Log.w(TAG, e);
}
}
/** {@hide} */
public ContentResolver(@Nullable Context context, @Nullable ContentInterface wrapped) {
mContext = context != null ? context : ActivityThread.currentApplication();
mPackageName = mContext.getOpPackageName();
mTargetSdkVersion = mContext.getApplicationInfo().targetSdkVersion;
mWrapped = wrapped;
}
/**
* Register a sync with the SyncManager. These requests are built using the
* {@link SyncRequest.Builder}.
*/
public static void requestSync(SyncRequest request) {
try {
// Note ActivityThread.currentPackageName() may not be accurate in a shared process
// case, but it's only for debugging.
getContentService().sync(request, ActivityThread.currentPackageName());
} catch(RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
private void createSystemContext() {
// 创建 system_server 上下文信息
ActivityThread activityThread = ActivityThread.systemMain();
mSystemContext = activityThread.getSystemContext();
mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
final Context systemUiContext = activityThread.getSystemUiContext();
// 设置主题,用于系统 dialog 等
systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
}
SystemBarBackgroundPainter( int windowFlags, int windowPrivateFlags, int sysUiVis,
int statusBarColor, int navigationBarColor) {
mWindowFlags = windowFlags;
mWindowPrivateFlags = windowPrivateFlags;
mSysUiVis = sysUiVis;
final Context context = ActivityThread.currentActivityThread().getSystemUiContext();
mStatusBarColor = DecorView.calculateStatusBarColor(windowFlags,
context.getColor(R.color.system_bar_background_semi_transparent),
statusBarColor);
mNavigationBarColor = navigationBarColor;
mStatusBarPaint.setColor(mStatusBarColor);
mNavigationBarPaint.setColor(navigationBarColor);
}
public ImmersiveModeConfirmation(Context context) {
mContext = ActivityThread.currentActivityThread().getSystemUiContext();
mHandler = new H();
mShowDelayMs = getNavBarExitDuration() * 3;
mPanicThresholdMs = context.getResources()
.getInteger(R.integer.config_immersive_mode_confirmation_panic);
mWindowManager = (WindowManager)
mContext.getSystemService(Context.WINDOW_SERVICE);
}
@Override
public void uncaughtException(Thread t, Throwable e) {
try {
ensureLogging(t, e);
// Don't re-enter -- avoid infinite loops if crash-reporting crashes.
if (mCrashing) return;
mCrashing = true;
// Try to end profiling. If a profiler is running at this point, and we kill the
// process (below), the in-memory buffer will be lost. So try to stop, which will
// flush the buffer. (This makes method trace profiling useful to debug crashes.)
if (ActivityThread.currentActivityThread() != null) {
ActivityThread.currentActivityThread().stopProfiling();
}
// Bring up crash dialog, wait for it to be dismissed
ActivityManager.getService().handleApplicationCrash(
mApplicationObject, new ApplicationErrorReport.ParcelableCrashInfo(e));
} catch (Throwable t2) {
if (t2 instanceof DeadObjectException) {
// System process is dead; ignore
} else {
try {
Clog_e(TAG, "Error reporting crash", t2);
} catch (Throwable t3) {
// Even Clog_e() fails! Oh well.
}
}
} finally {
// Try everything to make sure this process goes away.
Process.killProcess(Process.myPid());
System.exit(10);
}
}
/** Create an instance of ViolationInfo initialized from an exception. */
ViolationInfo(Violation tr, int policy) {
this.mViolation = tr;
this.mPolicy = policy;
violationUptimeMillis = SystemClock.uptimeMillis();
this.numAnimationsRunning = ValueAnimator.getCurrentAnimationsCount();
Intent broadcastIntent = ActivityThread.getIntentBeingBroadcast();
if (broadcastIntent != null) {
broadcastIntentAction = broadcastIntent.getAction();
}
ThreadSpanState state = sThisThreadSpanState.get();
if (tr instanceof InstanceCountViolation) {
this.numInstances = ((InstanceCountViolation) tr).getNumberOfInstances();
}
synchronized (state) {
int spanActiveCount = state.mActiveSize;
if (spanActiveCount > MAX_SPAN_TAGS) {
spanActiveCount = MAX_SPAN_TAGS;
}
if (spanActiveCount != 0) {
this.tags = new String[spanActiveCount];
Span iter = state.mActiveHead;
int index = 0;
while (iter != null && index < spanActiveCount) {
this.tags[index] = iter.mName;
index++;
iter = iter.mNext;
}
}
}
}
/**
* @hide to prevent subclassing from outside of the framework
*/
public Vibrator() {
mPackageName = ActivityThread.currentPackageName();
final Context ctx = ActivityThread.currentActivityThread().getSystemContext();
mDefaultHapticFeedbackIntensity = loadDefaultIntensity(ctx,
com.android.internal.R.integer.config_defaultHapticFeedbackIntensity);
mDefaultNotificationVibrationIntensity = loadDefaultIntensity(ctx,
com.android.internal.R.integer.config_defaultNotificationVibrationIntensity);
}
/** {@hide} */
public static @NonNull StorageVolume[] getVolumeList(int userId, int flags) {
final IStorageManager storageManager = IStorageManager.Stub.asInterface(
ServiceManager.getService("mount"));
try {
String packageName = ActivityThread.currentOpPackageName();
if (packageName == null) {
// Package name can be null if the activity thread is running but the app
// hasn't bound yet. In this case we fall back to the first package in the
// current UID. This works for runtime permissions as permission state is
// per UID and permission realted app ops are updated for all UID packages.
String[] packageNames = ActivityThread.getPackageManager().getPackagesForUid(
android.os.Process.myUid());
if (packageNames == null || packageNames.length <= 0) {
return new StorageVolume[0];
}
packageName = packageNames[0];
}
final int uid = ActivityThread.getPackageManager().getPackageUid(packageName,
PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
if (uid <= 0) {
return new StorageVolume[0];
}
return storageManager.getVolumeList(uid, packageName, flags);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Turn off the local Bluetooth adapter and don't persist the setting.
*
* <p>Requires the {@link android.Manifest.permission#BLUETOOTH_ADMIN}
* permission
*
* @return true to indicate adapter shutdown has begun, or false on immediate error
* @hide
*/
public boolean disable(boolean persist) {
try {
return mManagerService.disable(ActivityThread.currentPackageName(), persist);
} catch (RemoteException e) {
Log.e(TAG, "", e);
}
return false;
}
/**
* Stops an ongoing Bluetooth LE scan started using a PendingIntent. When creating the
* PendingIntent parameter, please do not use the FLAG_CANCEL_CURRENT flag. Otherwise, the stop
* scan may have no effect.
*
* @param callbackIntent The PendingIntent that was used to start the scan.
* @see #startScan(List, ScanSettings, PendingIntent)
*/
@RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
public void stopScan(PendingIntent callbackIntent) {
BluetoothLeUtils.checkAdapterStateOn(mBluetoothAdapter);
IBluetoothGatt gatt;
try {
gatt = mBluetoothManager.getBluetoothGatt();
gatt.stopScanForIntent(callbackIntent, ActivityThread.currentOpPackageName());
} catch (RemoteException e) {
}
}
/**
* Application interface registered - app is ready to go
*/
@Override
public void onScannerRegistered(int status, int scannerId) {
Log.d(TAG, "onScannerRegistered() - status=" + status
+ " scannerId=" + scannerId + " mScannerId=" + mScannerId);
synchronized (this) {
if (status == BluetoothGatt.GATT_SUCCESS) {
try {
if (mScannerId == -1) {
// Registration succeeds after timeout, unregister client.
mBluetoothGatt.unregisterClient(scannerId);
} else {
mScannerId = scannerId;
mBluetoothGatt.startScan(mScannerId, mSettings, mFilters,
mResultStorages,
ActivityThread.currentOpPackageName());
}
} catch (RemoteException e) {
Log.e(TAG, "fail to start le scan: " + e);
mScannerId = -1;
}
} else if (status == ScanCallback.SCAN_FAILED_SCANNING_TOO_FREQUENTLY) {
// applicaiton was scanning too frequently
mScannerId = -2;
} else {
// registration failed
mScannerId = -1;
}
notifyAll();
}
}
private static int getInt(String settings, int defaultValue) {
ContentResolver cr = null;
final ActivityThread at = ActivityThread.currentActivityThread();
if (at != null) {
cr = at.getApplication().getContentResolver();
}
if (cr == null) {
Log.w(TAG, "Could not read from " + settings + "; hardcoding " + defaultValue);
return defaultValue;
}
return Settings.Secure.getInt(cr, settings, defaultValue);
}
private void initAppOps() {
IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE);
mAppOps = IAppOpsService.Stub.asInterface(b);
// initialize mHasAppOpsPlayAudio
updateAppOpsPlayAudio();
// register a callback to monitor whether the OP_PLAY_AUDIO is still allowed
mAppOpsCallback = new IAppOpsCallbackWrapper(this);
try {
mAppOps.startWatchingMode(AppOpsManager.OP_PLAY_AUDIO,
ActivityThread.currentPackageName(), mAppOpsCallback);
} catch (RemoteException e) {
Log.e(TAG, "Error registering appOps callback", e);
mHasAppOpsPlayAudio = false;
}
}
public static void launch(String pkg) {
Context context = ActivityThread.currentActivityThread()
.getSystemContext();
Intent intent = context.getPackageManager().getLaunchIntentForPackage(
pkg);
startActivity(intent);
}
/**
* 反射替换ActivityThread的mInstrumentation
*/
private static void hookInstrumentation() {
PluginDebugLog.runtimeLog(TAG, "need to hook Instrumentation for plugin framework");
ActivityThread activityThread = ActivityThread.currentActivityThread();
Instrumentation hostInstr = getHostInstrumentation();
if (hostInstr != null) {
String hostInstrName = hostInstr.getClass().getName();
PluginDebugLog.runtimeLog(TAG, "host Instrument name: " + hostInstrName);
if (hostInstrName.startsWith("com.chaozhuo.superme")
|| hostInstrName.startsWith("com.lody.virtual")) {
// warning: 特殊case,VirtualApp环境,暂不Hook
PluginDebugLog.runtimeLog(TAG, "reject hook instrument, run in VirtualApp Environment");
} else if (hostInstr instanceof NeptuneInstrument) {
// already hooked
PluginDebugLog.runtimeLog(TAG, "ActivityThread Instrumentation already hooked");
} else {
PluginInstrument pluginInstrument = new NeptuneInstrument(hostInstr);
ReflectionUtils.on(activityThread).set("mInstrumentation", pluginInstrument);
PluginDebugLog.runtimeLog(TAG, "init hook ActivityThread Instrumentation success");
}
} else {
PluginDebugLog.runtimeLog(TAG, "init hook ActivityThread Instrumentation failed, hostInstr==null");
}
}
/**
* 获取ActivityThread的Instrumentation对象
*/
public static Instrumentation getHostInstrumentation() {
if (mHostInstr == null) {
ActivityThread activityThread = ActivityThread.currentActivityThread();
Instrumentation hostInstr = activityThread.getInstrumentation();
mHostInstr = PluginInstrument.unwrap(hostInstr);
}
return mHostInstr;
}
protected void hookIContentProviderAsNeeded() {
Uri uri = Uri.parse(RemoteContentProvider.getUri(mContext));
mContext.getContentResolver().call(uri, "wakeup", null, null);
try {
Field authority = null;
Field provider = null;
ActivityThread activityThread = ActivityThread.currentActivityThread();
Map providerMap = Reflector.with(activityThread).field("mProviderMap").get();
Iterator iter = providerMap.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
Object key = entry.getKey();
Object val = entry.getValue();
String auth;
if (key instanceof String) {
auth = (String) key;
} else {
if (authority == null) {
authority = key.getClass().getDeclaredField("authority");
authority.setAccessible(true);
}
auth = (String) authority.get(key);
}
if (auth.equals(RemoteContentProvider.getAuthority(mContext))) {
if (provider == null) {
provider = val.getClass().getDeclaredField("mProvider");
provider.setAccessible(true);
}
IContentProvider rawProvider = (IContentProvider) provider.get(val);
IContentProvider proxy = IContentProviderProxy.newInstance(mContext, rawProvider);
mIContentProvider = proxy;
Log.d(TAG, "hookIContentProvider succeed : " + mIContentProvider);
break;
}
}
} catch (Exception e) {
Log.w(TAG, e);
}
}