下面列出了android.os.Bundle#setClassLoader ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Test
public void test_beaconId_parcelable() {
BeaconId beaconId = new BeaconId(UUID.randomUUID(), 1, 2);
Parcel parcel = Parcel.obtain();
Bundle bundle = new Bundle();
bundle.putParcelable("some_value", beaconId);
bundle.writeToParcel(parcel, 0);
parcel.setDataPosition(0);
Bundle reverse = Bundle.CREATOR.createFromParcel(parcel);
reverse.setClassLoader(BeaconId.class.getClassLoader());
BeaconId beaconId2 = reverse.getParcelable("some_value");
Assertions.assertThat(beaconId.getMajorId()).isEqualTo(beaconId2.getMajorId());
Assertions.assertThat(beaconId.getMinorId()).isEqualTo(beaconId2.getMinorId());
Assertions.assertThat(beaconId.getUuid()).isEqualTo(beaconId2.getUuid());
Assertions.assertThat(beaconId).isEqualTo(beaconId2);
}
public void handleMessage(Message msg) {
if (this.mCallbacksMessengerRef != null) {
Bundle data = msg.getData();
data.setClassLoader(MediaSessionCompat.class.getClassLoader());
switch (msg.what) {
case 1:
this.mCallbackImpl.onServiceConnected((Messenger) this.mCallbacksMessengerRef.get(), data.getString(MediaBrowserProtocol.DATA_MEDIA_ITEM_ID), (Token) data.getParcelable(MediaBrowserProtocol.DATA_MEDIA_SESSION_TOKEN), data.getBundle(MediaBrowserProtocol.DATA_ROOT_HINTS));
return;
case 2:
this.mCallbackImpl.onConnectionFailed((Messenger) this.mCallbacksMessengerRef.get());
return;
case 3:
this.mCallbackImpl.onLoadChildren((Messenger) this.mCallbacksMessengerRef.get(), data.getString(MediaBrowserProtocol.DATA_MEDIA_ITEM_ID), data.getParcelableArrayList(MediaBrowserProtocol.DATA_MEDIA_ITEM_LIST), data.getBundle(MediaBrowserProtocol.DATA_OPTIONS));
return;
default:
Log.w(MediaBrowserCompat.TAG, "Unhandled message: " + msg + "\n Client version: " + 1 + "\n Service version: " + msg.arg1);
return;
}
}
}
/**
* 判断某个插件是否已经安装,通过aidl到{@link PluginPackageManagerService}中获取值,如果service不存在,
* 直接在sharedPreference中读取值,并且启动service
*
* @param pkgName 插件包名
* @return 返回是否安装
*/
public boolean isPackageInstalled(String pkgName) {
if (isConnected()) {
try {
return mService.isPackageInstalled(pkgName);
} catch (RemoteException e) {
// ignore
}
}
PluginDebugLog.runtimeLog(TAG, "isPackageInstalled, service is disconnected, need rebind");
onBindService(mContext);
boolean isInstalled = false;
if (ProcessUtils.isMainProcess(mContext)) {
isInstalled = mPackageManager.isPackageInstalled(pkgName);
} else {
// 其他进程通过ContentProvider处理
Bundle result = callRemoteProvider(PluginPackageManagerProvider.IS_PACKAGE_INSTALLED, pkgName);
if (result != null) {
result.setClassLoader(PluginLiteInfo.class.getClassLoader());
isInstalled = result.getBoolean(RESULT_KEY, false);
}
}
return isInstalled;
}
public static Fragment instantiate(Context context, String fname, @Nullable Bundle args) {
try {
Class<?> clazz = (Class) sClassMap.get(fname);
if (clazz == null) {
clazz = context.getClassLoader().loadClass(fname);
sClassMap.put(fname, clazz);
}
Fragment f = (Fragment) clazz.newInstance();
if (args != null) {
args.setClassLoader(f.getClass().getClassLoader());
f.mArguments = args;
}
return f;
} catch (ClassNotFoundException e) {
throw new InstantiationException("Unable to instantiate fragment " + fname + ": make sure class name exists, is public, and has an" + " empty constructor that is public", e);
} catch (InstantiationException e2) {
throw new InstantiationException("Unable to instantiate fragment " + fname + ": make sure class name exists, is public, and has an" + " empty constructor that is public", e2);
} catch (IllegalAccessException e3) {
throw new InstantiationException("Unable to instantiate fragment " + fname + ": make sure class name exists, is public, and has an" + " empty constructor that is public", e3);
}
}
@Override
public void restoreState(Parcelable state, ClassLoader loader) {
if (state != null) {
Bundle bundle = (Bundle) state;
bundle.setClassLoader(loader);
Parcelable[] fss = bundle.getParcelableArray("states");
mSavedState.clear();
if (fss != null) {
for (Parcelable fs : fss) {
mSavedState.add((Fragment.SavedState) fs);
}
}
Iterable<String> keys = bundle.keySet();
for (String key : keys) {
if (key.startsWith("f")) {
Fragment f = mFragmentManager.getFragment(bundle, key);
if (f != null) {
f.setMenuVisibility(false);
} else {
Log.w(TAG, "Bad fragment at key " + key);
}
}
}
}
}
@Override
public void restoreState(Parcelable state, ClassLoader loader) {
if (state != null) {
Bundle b=(Bundle)state;
b.setClassLoader(getClass().getClassLoader());
entries=((Bundle)state).getParcelableArrayList(KEY_DESCRIPTORS);
notifyDataSetChanged();
}
}
/**
* Retrieve the last {@link Bundle} stored as a long-lived cached object
* within the system.
*
* @return {@code null} if no cached object has been stored, or if the
* stored object has been invalidated due to a
* {@link #notifyChange(Uri, ContentObserver)} event.
* @hide
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.CACHE_CONTENT)
public @Nullable Bundle getCache(@NonNull Uri key) {
try {
final Bundle bundle = getContentService().getCache(mContext.getPackageName(), key,
mContext.getUserId());
if (bundle != null) bundle.setClassLoader(mContext.getClassLoader());
return bundle;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
public void handleMessage(Message msg) {
switch (msg.what) {
case SensorbergServiceMessage.MSG_PRESENT_ACTION:
Bundle bundle = msg.getData();
bundle.setClassLoader(BeaconEvent.class.getClassLoader());
BeaconEvent beaconEvent = bundle.getParcelable(SensorbergServiceMessage.MSG_PRESENT_ACTION_BEACONEVENT);
notifyEventListeners(beaconEvent);
break;
default:
super.handleMessage(msg);
}
}
@Override
public void handleMessage(@NonNull android.os.Message msg) {
super.handleMessage(msg);
Bundle bundle = msg.getData();
bundle.setClassLoader(Message.class.getClassLoader());
Message message = bundle.getParcelable("message");
Toast.makeText(MainActivity.this, String.valueOf(message.getContent()), Toast.LENGTH_SHORT).show();
}
public static SettingsData fromBundle(@NonNull Bundle bundle) {
bundle.setClassLoader(Region.class.getClassLoader());
SettingsData settingsData = null;
if (bundle.get(SETTINGS_DATA_KEY) != null) {
settingsData = (SettingsData) bundle.getSerializable(SETTINGS_DATA_KEY);
}
return settingsData;
}
/**
* @param view the view to return the parameters from.
* @return the start parameters of the view/presenter
*/
@Nullable public Bundle getParameters(@NonNull Object view) {
final Iterator<ViewStackEntry> viewStackEntryIterator = viewStack.descendingIterator();
while (viewStackEntryIterator.hasNext()) {
final ViewStackEntry viewStackEntry = viewStackEntryIterator.next();
if (view == viewStackEntry.viewReference.get()) {
final Bundle bundle = viewStackEntry.parameters;
if (bundle != null) {
bundle.setClassLoader(view.getClass().getClassLoader());
}
return bundle;
}
}
return null;
}
public static StartRMData fromBundle(@NonNull Bundle bundle) {
bundle.setClassLoader(Region.class.getClassLoader());
boolean valid = false;
StartRMData data = new StartRMData();
if (bundle.containsKey(REGION_KEY)) {
data.mRegion = (Region)bundle.getSerializable(REGION_KEY);
valid = true;
}
if (bundle.containsKey(SCAN_PERIOD_KEY)) {
data.mScanPeriod = (Long) bundle.get(SCAN_PERIOD_KEY);
valid = true;
}
if (bundle.containsKey(BETWEEN_SCAN_PERIOD_KEY)) {
data.mBetweenScanPeriod = (Long) bundle.get(BETWEEN_SCAN_PERIOD_KEY);
}
if (bundle.containsKey(BACKGROUND_FLAG_KEY)) {
data.mBackgroundFlag = (Boolean) bundle.get(BACKGROUND_FLAG_KEY);
}
if (bundle.containsKey(CALLBACK_PACKAGE_NAME_KEY)) {
data.mCallbackPackageName = (String) bundle.get(CALLBACK_PACKAGE_NAME_KEY);
}
if (valid) {
return data;
}
else {
return null;
}
}
public static final IBinder getBinder(Cursor cursor) {
Bundle extras = cursor.getExtras();
extras.setClassLoader(BinderCursor.class.getClassLoader());
BinderParcelable w = (BinderParcelable) extras.getParcelable(BINDER_KEY);
if (LOG) {
LogDebug.d(PLUGIN_TAG, "get binder = " + w.mBinder);
}
return w.mBinder;
}
@Override
public void callActivityOnRestoreInstanceState(Activity activity, Bundle savedInstanceState) {
if (activity instanceof TransRecoveryActivity1) {
mRecoveryHelper.saveSavedInstanceState(activity, savedInstanceState);
return;
}
if (IntentUtils.isIntentForPlugin(activity.getIntent())) {
String pkgName = IntentUtils.parsePkgAndClsFromIntent(activity.getIntent())[0];
PluginLoadedApk loadedApk = PluginManager.getPluginLoadedApkByPkgName(pkgName);
if (loadedApk != null && savedInstanceState != null) {
savedInstanceState.setClassLoader(loadedApk.getPluginClassLoader());
}
}
mHostInstr.callActivityOnRestoreInstanceState(activity, savedInstanceState);
}
@Override
public void restoreState(Parcelable state, ClassLoader loader) {
if (state != null) {
Bundle bundle = (Bundle) state;
bundle.setClassLoader(loader);
Parcelable[] fss = bundle.getParcelableArray("states");
mSavedState.clear();
mFragments.clear();
if (fss != null) {
for (Parcelable fs : fss) {
mSavedState.add((Fragment.SavedState) fs);
}
}
Iterable<String> keys = bundle.keySet();
for (String key : keys) {
if (key.startsWith("f")) {
int index = Integer.parseInt(key.substring(1));
Fragment f = mFragmentManager.getFragment(bundle, key);
if (f != null) {
while (mFragments.size() <= index) {
mFragments.add(null);
}
f.setMenuVisibility(false);
mFragments.set(index, f);
} else {
Log.w(TAG, "Bad fragment at key " + key);
}
}
}
}
}
@Override
public List<ChooserTarget> onGetChooserTargets(ComponentName targetActivityName,
IntentFilter matchedFilter)
{
List<ChooserTarget> results = new LinkedList<>();
ComponentName componentName = new ComponentName(this, ShareActivity.class);
ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(this);
Cursor cursor = threadDatabase.getRecentConversationList(10, false);
try {
ThreadDatabase.Reader reader = threadDatabase.readerFor(cursor);
ThreadRecord record;
while ((record = reader.getNext()) != null) {
Recipient recipient = Recipient.resolved(record.getRecipient().getId());
String name = recipient.toShortString(this);
Bitmap avatar;
if (recipient.getContactPhoto() != null) {
try {
avatar = GlideApp.with(this)
.asBitmap()
.load(recipient.getContactPhoto())
.circleCrop()
.submit(getResources().getDimensionPixelSize(android.R.dimen.notification_large_icon_width),
getResources().getDimensionPixelSize(android.R.dimen.notification_large_icon_width))
.get();
} catch (InterruptedException | ExecutionException e) {
Log.w(TAG, e);
avatar = getFallbackDrawable(recipient);
}
} else {
avatar = getFallbackDrawable(recipient);
}
Bundle bundle = new Bundle();
bundle.putLong(ShareActivity.EXTRA_THREAD_ID, record.getThreadId());
bundle.putString(ShareActivity.EXTRA_RECIPIENT_ID, recipient.getId().serialize());
bundle.putInt(ShareActivity.EXTRA_DISTRIBUTION_TYPE, record.getDistributionType());
bundle.setClassLoader(getClassLoader());
results.add(new ChooserTarget(name, Icon.createWithBitmap(avatar), 1.0f, componentName, bundle));
}
return results;
} finally {
if (cursor != null) cursor.close();
}
}
public void restoreState(Parcelable parcelable, ClassLoader classloader)
{
if (parcelable != null)
{
Bundle bundle = (Bundle)parcelable;
bundle.setClassLoader(classloader);
Parcelable aparcelable[] = bundle.getParcelableArray("states");
e.clear();
f.clear();
if (aparcelable != null)
{
for (int j = 0; j < aparcelable.length; j++)
{
e.add((android.app.Fragment.SavedState)aparcelable[j]);
}
}
Iterator iterator = bundle.keySet().iterator();
do
{
if (!iterator.hasNext())
{
break;
}
String s = (String)iterator.next();
if (s.startsWith("f"))
{
int i = Integer.parseInt(s.substring(1));
Fragment fragment = c.getFragment(bundle, s);
if (fragment != null)
{
for (; f.size() <= i; f.add(null)) { }
FragmentCompat.setMenuVisibility(fragment, false);
f.set(i, fragment);
} else
{
Log.w("FragmentStatePagerAdapter", (new StringBuilder()).append("Bad fragment at key ").append(s).toString());
}
}
} while (true);
}
}
public static RecipesRecord fromBundle(Bundle bundle, String key) {
bundle.setClassLoader(RecipesRecord.class.getClassLoader());
return bundle.getParcelable(key);
}
@Override
public void handleMessage(Message msg) {
if(this.provider.get() == null){
return;
}
SdlRouterService service = this.provider.get();
Bundle receivedBundle = msg.getData();
switch(msg.what){
case TransportConstants.HARDWARE_CONNECTION_EVENT:
if(receivedBundle.containsKey(TransportConstants.HARDWARE_DISCONNECTED)){
//We should shut down, so call
if(altTransportService != null
&& altTransportService.equals(msg.replyTo)){
//The same transport that was connected to the router service is now telling us it's disconnected. Let's inform clients and clear our saved messenger
altTransportService = null;
service.onTransportDisconnected(new TransportRecord(TransportType.valueOf(receivedBundle.getString(TransportConstants.HARDWARE_DISCONNECTED)),null));
service.shouldServiceRemainOpen(null); //this will close the service if bluetooth is not available
}
}else if(receivedBundle.containsKey(TransportConstants.HARDWARE_CONNECTED)){
Message retMsg = Message.obtain();
retMsg.what = TransportConstants.ROUTER_REGISTER_ALT_TRANSPORT_RESPONSE;
if(altTransportService == null){ //Ok no other transport is connected, this is good
Log.d(TAG, "Alt transport connected.");
if(msg.replyTo == null){
break;
}
altTransportService = msg.replyTo;
//Clear out the timer to make sure the service knows we're good to go
if(service.altTransportTimerHandler!=null && service.altTransportTimerRunnable!=null){
service.altTransportTimerHandler.removeCallbacks(service.altTransportTimerRunnable);
}
service.altTransportTimerHandler = null;
service.altTransportTimerRunnable = null;
//Let the alt transport know they are good to go
retMsg.arg1 = TransportConstants.ROUTER_REGISTER_ALT_TRANSPORT_RESPONSE_SUCESS;
service.onTransportConnected(new TransportRecord(TransportType.valueOf(receivedBundle.getString(TransportConstants.HARDWARE_CONNECTED)),null));
}else{ //There seems to be some other transport connected
//Error
retMsg.arg1 = TransportConstants.ROUTER_REGISTER_ALT_TRANSPORT_ALREADY_CONNECTED;
}
if(msg.replyTo!=null){
try {msg.replyTo.send(retMsg);} catch (RemoteException e) {e.printStackTrace();}
}
}
break;
case TransportConstants.ROUTER_RECEIVED_PACKET:
if(receivedBundle!=null){
receivedBundle.setClassLoader(loader);//We do this because loading a custom parcelable object isn't possible without it
if(receivedBundle.containsKey(TransportConstants.FORMED_PACKET_EXTRA_NAME)){
SdlPacket packet = receivedBundle.getParcelable(TransportConstants.FORMED_PACKET_EXTRA_NAME);
if(packet!=null){
service.onPacketRead(packet);
}else{
Log.w(TAG, "Received null packet from alt transport service");
}
}else{
Log.w(TAG, "False positive packet reception");
}
}else{
Log.e(TAG, "Bundle was null while sending packet to router service from alt transport");
}
break;
default:
super.handleMessage(msg);
}
}
/**
* Paste clipboard content between min and max positions.
* If clipboard content contain the MentionSpan, set the span in copied text.
*/
private void paste(@IntRange(from = 0) int min, @IntRange(from = 0) int max) {
ClipboardManager clipboard = (ClipboardManager) getContext().getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = clipboard.getPrimaryClip();
if (clip != null) {
for (int i = 0; i < clip.getItemCount(); i++) {
ClipData.Item item = clip.getItemAt(i);
String selectedText = item.coerceToText(getContext()).toString();
MentionsEditable text = getMentionsText();
MentionSpan[] spans = text.getSpans(min, max, MentionSpan.class);
/*
* We need to remove the span between min and max. This is required because in
* {@link SpannableStringBuilder#replace(int, int, CharSequence)} existing spans within
* the Editable that entirely cover the replaced range are retained, but any that
* were strictly within the range that was replaced are removed. In our case the existing
* spans are retained if the selection entirely covers the span. So, we just remove
* the existing span and replace the new text with that span.
*/
for (MentionSpan span : spans) {
if (text.getSpanEnd(span) == min) {
// We do not want to remove the span, when we want to paste anything just next
// to the existing span. In this case "text.getSpanEnd(span)" will be equal
// to min.
continue;
}
text.removeSpan(span);
}
Intent intent = item.getIntent();
// Just set the plain text if we do not have mentions data in the intent/bundle
if (intent == null) {
text.replace(min, max, selectedText);
continue;
}
Bundle bundle = intent.getExtras();
if (bundle == null) {
text.replace(min, max, selectedText);
continue;
}
bundle.setClassLoader(getContext().getClassLoader());
int[] spanStart = bundle.getIntArray(KEY_MENTION_SPAN_STARTS);
Parcelable[] parcelables = bundle.getParcelableArray(KEY_MENTION_SPANS);
if (parcelables == null || parcelables.length <= 0 || spanStart == null || spanStart.length <= 0) {
text.replace(min, max, selectedText);
continue;
}
// Set the MentionSpan in text.
SpannableStringBuilder s = new SpannableStringBuilder(selectedText);
for (int j = 0; j < parcelables.length; j++) {
MentionSpan mentionSpan = (MentionSpan) parcelables[j];
s.setSpan(mentionSpan, spanStart[j], spanStart[j] + mentionSpan.getDisplayString().length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
text.replace(min, max, s);
}
}
}