2014-12-16 10:06

1.

android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
at android.app.ContextImpl.startActivity(ContextImpl.java:1161)
at android.app.ContextImpl.startActivity(ContextImpl.java:1148)

原因是:
  Context中有一个startActivity方法,Activity继承自Context,重载了startActivity方法。如果使用 Activity的startActivity方法,不会有任何限制,而如果使用Context的startActivity方法的话,就需要开启一个新的task,遇到上面那个异常的,都是因为使用了Context的startActivity方法。解决办法是,加一个flag。intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);


2.

FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS:
如果调出的Activtivity只是一个功能片段,并没有实际的意义,也没有必要出现在长按Home键调出最近使用过的程序类表中,那么使用FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
Intent intent = new Intent(this, TestActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
startActivity(intent);

==========================================================================================

==========================================================================================

2015年01月12号

3.Android4.4.X版本,开启或关闭飞行模式时,报出异常:

E/AndroidRuntime(2775):FATALEXCEPTION:main E/AndroidRuntime(2775):Process:com.android.deskclock,PID:2775 E/AndroidRuntime(2775):java.lang.SecurityException:PermissionDenial:notallowedtosendbroadcastandroid.intent.action.AIRPLANE_MODEfrompid=2775,uid=10057 E/AndroidRuntime(2775): atandroid.os.Parcel.readException(Parcel.java:1472) E/AndroidRuntime(2775): atandroid.os.Parcel.readException(Parcel.java:1426) E/AndroidRuntime(2775): atandroid.app.ActivityManagerProxy.broadcastIntent(ActivityManagerNative.java:2491) E/AndroidRuntime(2775): atandroid.app.ContextImpl.sendBroadcast(ContextImpl.java:1243) E/AndroidRuntime(2775): atandroid.content.ContextWrapper.sendBroadcast(ContextWrapper.java:365) E/AndroidRuntime(2775): atcom.android.deskclock.alarmclock.Alarms.closeAirplaneMode(Alarms.java:1863) E/AndroidRuntime(2775): atcom.android.deskclock.alarmclock.LockAlarmFullActivity$ControlAlarm.dismiss(LockAlarmFullActivity.java:955) E/AndroidRuntime(2775): atcom.android.deskclock.alarmclock.LockAlarmFullActivity$4.onTouch(LockAlarmFullActivity.java:617) E/AndroidRuntime(2775): atandroid.view.View.dispatchTouchEvent(View.java:7780) E/AndroidRuntime(2775): atandroid.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2316)

虽然已经在AndroidManifest.xml声明了权限,但是依旧会报出异常。后查需要在AndroidManifest.xml 添加android:sharedUserId="android.uid.system"

如果上面方法仍不奏效,那么可以使该apk的签名和平台保持一致。即使用源码平台默认签名对该apk进行重新签名,并push到 systen/app下面。那么操作Setttings表时就具有了系统权限。

==========================================================================================

==========================================================================================


2015年01月15日:

4.

Android平台继承SQLiteOpenHelper实现的CRUD操作,默认情况不允许数据库降级,否则显示会抛出异常: thrownewSQLiteException("Can'tdowngradedatabasefromversion"+oldVersion+"to"+newVersion);
01-14 20:29:22.290: E/AndroidRuntime(2722): FATAL EXCEPTION: AsyncHandler 01-14 20:29:22.290: E/AndroidRuntime(2722): Process: com.android.deskclock, PID: 2722 01-14 20:29:22.290: E/AndroidRuntime(2722): android.database.sqlite.SQLiteException: Can't downgrade database from version 10 to 7 01-14 20:29:22.290: E/AndroidRuntime(2722): at android.database.sqlite.SQLiteOpenHelper.onDowngrade(SQLiteOpenHelper.java:361) 01-14 20:29:22.290: E/AndroidRuntime(2722): at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:255)

    /** * Called when the database needs to be downgraded. This is strictly similar to * {@link #onUpgrade} method, but is called whenever current version is newer than requested one. * However, this method is not abstract, so it is not mandatory for a customer to * implement it. If not overridden, default implementation will reject downgrade and * throws SQLiteException * * <p> * This method executes within a transaction. If an exception is thrown, all changes * will automatically be rolled back. * </p> * * @param db The database. * @param oldVersion The old database version. * @param newVersion The new database version. */    public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {        throw new SQLiteException("Can't downgrade database from version " +                oldVersion + " to " + newVersion);    }


当然可以复写父类方法允许数据库降级,前提是对数据库版本号毫不关心。因此通常不会去复写该方法,因为: Youshouldcareaboutthis"DatabaseVersionthing"ifeveryourdatabaseschemaisevergoingtochange

==========================================================================================

==========================================================================================


2015年01月26日:

5.WindowManager$BadTokenException: Unable to add window…is not valid; is your activity running?

01-26 11:20:07.365 11836 11836 E AndroidRuntime: Process: com.mediatek.schpwronoff, PID: 11836
01-26 11:20:07.365 11836 11836 E AndroidRuntime: android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@41f06b68 is not valid; is your activity running?
01-26 11:20:07.365 11836 11836 E AndroidRuntime: at android.view.ViewRootImpl.setView(ViewRootImpl.java:637)
01-26 11:20:07.365 11836 11836 E AndroidRuntime: at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:261)
01-26 11:20:07.365 11836 11836 E AndroidRuntime: at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
01-26 11:20:07.365 11836 11836 E AndroidRuntime: at android.app.Dialog.show(Dialog.java:329)
01-26 11:20:07.365 11836 11836 E AndroidRuntime: at android.app.Activity.showDialog(Activity.java:3182)
01-26 11:20:07.365 11836 11836 E AndroidRuntime: at android.app.Activity.showDialog(Activity.java:3132)
01-26 11:20:07.365 11836 11836 E AndroidRuntime: at com.mediatek.schpwronoff.ShutdownActivity$1.onTick(ShutdownActivity.java:93)
01-26 11:20:07.365 11836 11836 E AndroidRuntime: at android.os.CountDownTimer$1.handleMessage(CountDownTimer.java:124)
01-26 11:20:07.365 11836 11836 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:110)
01-26 11:20:07.365 11836 11836 E AndroidRuntime: at android.os.Looper.loop(Looper.java:193)
01-26 11:20:07.365 11836 11836 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:5332)
01-26 11:20:07.365 11836 11836 E AndroidRuntime: at java.lang.reflect.Method.invokeNative(Native Method)
01-26 11:20:07.365 11836 11836 E AndroidRuntime: at java.lang.reflect.Method.invoke(Method.java:515)
01-26 11:20:07.365 11836 11836 E AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:831)
01-26 11:20:07.365 11836 11836 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:647)
01-26 11:20:07.365 11836 11836 E AndroidRuntime: at dalvik.system.NativeStart.main(Native Method)

======================================================

FATAL EXCEPTION: main
android.view.WindowManager$BadTokenException: Unable to add window -- token android.app.LocalActivityManager$LocalActivityRecord@4051c0e0 is not valid; is your activity running?
at android.view.ViewRoot.setView(ViewRoot.java:558)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
at android.view.Window$LocalWindowManager.addView(Window.java:433)
at android.app.Dialog.show(Dialog.java:265)
at net.reecam.CameraSearch$3.onClick(CameraSearch.java:103)
at android.view.View.performClick(View.java:2532)
at android.view.View$PerformClick.run(View.java:9308)
at android.os.Handler.handleCallback(Handler.java:587)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:150)
at android.app.ActivityThread.main(ActivityThread.java:4293)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
at dalvik.system.NativeStart.main(Native Method)

问题原因:
看报错关键词提示:Unable to add window 、LocalActivityManager、is your activity running,再结合应用程序中用到了AcitivityGroup来管理子Activity这个环境,而报错的前提就是在子Activity上弹出ProgressDialog进度条会话框,提示如上报错提示。就是说不能在子Activity上添加此窗口,LocalActivityManager$LocalActivityRecord@4051c0e0 is not valid就是说当前Activity管理器中此4051c0e0代表的Acitivity是无效的,也就是网上资料所说找不到它依附的Acitivity。

解决办法:
将new DialogToast(this);
改为:
new DialogToast(getParent());
就OK了。


是由于有activity时依附于另一个activity的,当被依附的activity产生错误的时候,该activity没有了靠山而产生错误(或者是调用了一个已经被finish()的activity)。一般在创建alertdialog.builder是很容易见到。

对于这个错误还没有根本的解决办法,唯一的办法就是改变该activity依附于另一activity的事实,将其放入另一activity。


Android利用ActivityGroup加载子Activity,子Activity调用对话框,弹出:

ERROR/AndroidRuntime(10104): Caused by: android.view.WindowManager$BadTokenException: Unable to add window -- token android.app.LocalActivityManager$LocalActivityRecord@45a58ee0 is not valid; is your activity running?

原因分析:

因为new对话框的时候,参数content 指定成了this,即指向当前子Activity的content。但子Activity是动态创建的,不能保证一直存在。其父Activity的content是稳定存在的,所以有下面的解决办法。

解决办法:

将content替换为getParent()即可。

==========================================================================================

==========================================================================================


2015年01月27

6.android.os.BadParcelableException: ClassNotFoundException when unmarshalling:解决办法

例如在用AlarmManager的时候

 1 AlarmManager alarmMgr = (AlarmManager) mContext  2  .getSystemService(Context.ALARM_SERVICE);  3         Intent intent = new Intent(ALARM_ALERT);  4       // intent.setExtrasClassLoader(DBTask.class.getClassLoader());  5         Bundle mBundle=new Bundle();  6  mBundle.putParcelable(AlarmMeReceiver.DB_TASK_KEY,task);  7  intent.putExtras(mBundle);  8         int id=Integer.valueOf(task.id);  9         PendingIntent pendIntent = PendingIntent.getBroadcast( 10  mContext.getApplicationContext(), id, intent, 11  PendingIntent.FLAG_UPDATE_CURRENT); 12         long triggerAtTime = task.time; 13         alarmMgr.set(AlarmManager.RTC_WAKEUP , triggerAtTime, pendIntent);

通过第6行 intent传提一个Parcelable对象 (Parcelable里面没有问题)

android.os.BadParcelableException: ClassNotFoundException when unmarshalling错误可以加上

intent.setExtrasClassLoader(DBTask.class.getClassLoader());

原因是android.platform.frameworks.base/core/java/android/content/Intent.java

5052             try { 5053                 Bundle newb = new Bundle(other.mExtras); 5054 newb.putAll(mExtras); 5055                 mExtras = newb; 5056             } catch (RuntimeException e) { 5057                 // Modifying the extras can cause us to unparcel the contents5058                 // of the bundle, and if we do this in the system process that5059                 // may fail. We really should handle this (i.e., the Bundle5060                 // impl shouldn't be on top of a plain map), but for now just5061                 // ignore it and keep the original contents. :(5062                 Log.w("Intent", "Failure filling in extras", e); 5063             }

android 中自定义的对象序列化的问题有两个选择一个是Parcelable,另外一个是Serializable。

一 序列化原因:

1.永久性保存对象,保存对象的字节序列到本地文件中;
2.通过序列化对象在网络中传递对象;
3.通过序列化在进程间传递对象。

二 至于选取哪种可参考下面的原则:

1.在使用内存的时候,Parcelable 类比Serializable性能高,所以推荐使用Parcelable类。
2.Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC。
3.Parcelable不能使用在要将数据存储在磁盘上的情况,因为Parcelable不能很好的保证数据的持续性在外界有变化的情况下。尽管Serializable效率低点, 也不提倡用,但在这种情况下,还是建议你用Serializable 。


==============================================================================================================

android.os.BadParcelableException: ClassNotFoundException when unmarshalling

本文主要分析android.os.BadParcelableException: ClassNotFoundException when unmarshalling这个异常的原因及解决方法,解释了android的class loader.

一、现象:
应用打开,home键到后台,过一段时间打开,偶现fc,log如下:

1 2 3 E/AndroidRuntime(9085): Caused by: android.os.BadParcelableException: ClassNotFoundException when unmarshalling: *.*.*.*.Layout$Config E/AndroidRuntime(9085): at android.os.Parcel.readParcelable(Parcel.java:2077) E/AndroidRuntime(9085): at *.*.*.<init>(Layout.java:105)

程序中的写法是

Java
1 2 3 4 5 6 7 publicConfigconfig; publicRowView(Parcelin){ type=in.readString(); interfaceUrl=in.readString(); size=in.readInt(); config=in.readParcelable(null); }

报错的语句即为config = in.readParcelable(null);

二、原因分析:
根据android文档介绍:
readParcelable (ClassLoader loader)
loader A ClassLoader from which to instantiate the Parcelable object, or null for the default class loader.
即loader为空时系统会采取默认的class loader。

Android有两种不同的classloaders:framework classloader和apk classloader,其中framework classloader知道怎么加载android classes,apk classloader知道怎么加载you code,apk classloader继承自framework classloader,所以也知道怎么加载android classes。

在应用刚启动时,默认class loader是apk classloader,但在系统内存不足应用被系统回收会再次启动,这个默认class loader会变为framework classloader了,所以对于自己的类会报ClassNotFoundException。

三、解决方法:
将config = in.readParcelable(null);改为config = in.readParcelable(Config.class.getClassLoader());
Config.class.getClassLoader()即为apk classloader, 其中Config.class可以改为你程序中自己写的任意类,因为他们同样指向apk loader
嘿嘿,试着改为config = in.readParcelable(Activity.class.getClassLoader());你会发现依然ClassNotFoundException因为Activity.class.getClassLoader()指向的是framework classloader

四、如何测试重现这个问题,方便测试呢:
重现这个问题即使的应用被系统回收,把设置->开发者选项->不保留活动开关打开,打开测试程序按home键,再打开测试程序就会执行到这句。

如果你是在onSaveInstanceState中保存
savedInstanceState.putParcelable(key, value),则需要设置Bundle的class loader,如下:
savedInstanceState.setClassLoader(getClass().getClassLoader());

PS:
(1)、readParcelableArray(ClassLoader loader), readParcelable, readArray,readArrayList, readBundle, readHashMap, readParcelable, readSparseArray, readValue, readList, readMap也有可能报上面的异常

相关博客:

关于Parcelable以及Parcelable和Serializable的区别的区别,可参考以前写的:http://www.cnblogs.com/trinea/archive/2012/11/09/2763213.html
参考:http://stackoverflow.com/questions/13997550/unmarshalling-errors-in-android-app-with-custom-parcelable-classes
http://developer.android.com/reference/android/os/Parcel.html#readParcelable(java.lang.ClassLoader



=========================================================================================

关于这个“Activity之间对象传递的两种方法(Serializable,Parcelable)”我是通过别人的博客里学习到的,引用自:http://blog.csdn.net/Android_Tutor/archive/2010/07/16/5740845.aspx

本来是要直接附上Demo的,可惜这里面没找到加入本地文件的地方。大家需要的还是到作者那去看看吧。

首先,我这里主要说下Parcelable 的用法。

1、定义对象类,类实现Parcelable接口。且要实现Parcelable接口的几个必要方法。如我的Question类中的相关方法的实现:

private Question(Parcel in){
question_title = ParcelUtils.readStringFromParcel(in);

created_time = ParcelUtils.readStringFromParcel(in);
question_id = in.readInt();

creator_name = ParcelUtils.readStringFromParcel(in);
answer_list = new Group<Answer>();
int answerSize = in.readInt();
for (int i = 0; i < answerSize; i++) {
Answer answer = in.readParcelable(Answer.class.getClassLoader());
answer_list.add(answer);
}

}

public static final Question.Creator<Question> CREATOR = new Parcelable.Creator<Question>() {
public Question createFromParcel(Parcel in) {
return new Question(in);
}

@Override
public Question[] newArray(int size) {
return new Question[size];
}
};

@Override
public void writeToParcel(Parcel out, int flags) {

ParcelUtils.writeStringToParcel(out, question_title);

ParcelUtils.writeStringToParcel(out, created_time);
out.writeInt(question_id);

ParcelUtils.writeStringToParcel(out, creator_name);
if (answer_list != null) {
out.writeInt(answer_list.size());
for (int i = 0; i < answer_list.size(); i++) {
out.writeParcelable(answer_list.get(i), flags);
}
} else {
out.writeInt(0);
}
}

注意:

方法private Question(Parcel in){}和方法public void writeToParcel(Parcel out, int flags) {}中变量顺序是一致的,是一一对应的。其中,

Question(Parcel in)是变量的存储;

writeToParcel(Parcel out, int flags) 是变量的读取。

2、程序中的应用:

1)存储

Intent intent = new Intent(Question1.this,Question2.class);
Bundle bundle = new Bundle();
bundle.putParcelable("question_objs", question);
intent.putExtras(bundle);
startActivity(intent);

2)提取
Intent intent = getIntent();

Question que = intent.getParcelableExtra("question_objs");

3)接下来就可以使用question对象了。

其次,在使用Parcelable的过程中,曾报异常:

Caused By:android.os.BadParcelableException: ClassNotFoundException when unmarshalling:

at android.os.Parcel.readParcelable(Parcel.java )

该异常是由于,我在对象类得定义中,成员变量的读取和存储没有一一对应,导致成员变量赋值错误,从而导致上述异常,所以,在上述对象类的定义说明中加了“注意:



更多相关文章

  1. 浅谈Java中Collections.sort对List排序的两种方法
  2. 类和 Json对象
  3. Python list sort方法的具体使用
  4. python list.sort()根据多个关键字排序的方法实现
  5. android volley 上传文件
  6. Android(安卓)调用.NET webservice
  7. Android(安卓)Studio 更新SDK 腾讯镜像使用方法
  8. android onSaveInstanceState的使用方法
  9. Android(安卓)获取屏幕分辨率

随机推荐

  1. Android屏幕适配总结终极方案
  2. Android_TextView属性XML详解
  3. Android测试驱动开发实践1
  4. Android计算器——入门
  5. Android(安卓)ADT,SDK的安装,让人烦恼的在
  6. 我和我的Android
  7. Android(安卓)内存泄漏调试
  8. Android内核开发:理解和掌握repo工具
  9. Android开发已经没人要了么?
  10. Android中使用Notification