崩溃时使用ViewFlipper旋转活动 [英] Crash when rotating Activity using ViewFlipper
问题描述
我本来有两个ListActivity类。
我尝试用含1活动,并使用ViewFlipper,两个列表之间翻转。
这似乎除了一个问题是工作的伟大。如果我旋转模拟器,我会随机得到一个崩溃。它不会发生,每次我想不出一个具体的工作流程来触发它。这是错误:
01-12 16:28:58.292:WARN / dalvikvm(877):主题ID = 3:线程退出与未捕获的异常(组= 0x4001b188)
01-12 16:28:58.292:ERROR / AndroidRuntime(877):未捕获的处理程序:螺纹主力退出,由于未捕获的异常
01-12 16:28:58.312:ERROR / AndroidRuntime(877):java.lang.IllegalArgumentException:如果接收器未注册:android.widget.ViewFlipper$1@43d44458
01-12 16:28:58.312:ERROR / AndroidRuntime(877):在android.app.ActivityThread $ PackageInfo.forgetReceiverDispatcher(ActivityThread.java:667)
01-12 16:28:58.312:ERROR / AndroidRuntime(877):在android.app.ApplicationContext.unregisterReceiver(ApplicationContext.java:747)
01-12 16:28:58.312:ERROR / AndroidRuntime(877):在android.content.ContextWrapper.unregisterReceiver(ContextWrapper.java:321)
01-12 16:28:58.312:ERROR / AndroidRuntime(877):在android.widget.ViewFlipper.onDetachedFromWindow(ViewFlipper.java:104)
01-12 16:28:58.312:ERROR / AndroidRuntime(877):在android.view.View.dispatchDetachedFromWindow(View.java:5835)
01-12 16:28:58.312:ERROR / AndroidRuntime(877):在android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:1076)
01-12 16:28:58.312:ERROR / AndroidRuntime(877):在android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:1074)
01-12 16:28:58.312:ERROR / AndroidRuntime(877):在android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:1074)
01-12 16:28:58.312:ERROR / AndroidRuntime(877):在android.view.ViewRoot.dispatchDetachedFromWindow(ViewRoot.java:1570)
01-12 16:28:58.312:ERROR / AndroidRuntime(877):在android.view.ViewRoot.doDie(ViewRoot.java:2556)
01-12 16:28:58.312:ERROR / AndroidRuntime(877):在android.view.ViewRoot.die(ViewRoot.java:2526)
01-12 16:28:58.312:ERROR / AndroidRuntime(877):在android.view.WindowManagerImpl.removeViewImmediate(WindowManagerImpl.java:218)
01-12 16:28:58.312:ERROR / AndroidRuntime(877):在android.view.Window $ LocalWindowManager.removeViewImmediate(Window.java:436)
01-12 16:28:58.312:ERROR / AndroidRuntime(877):在android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3498)
01-12 16:28:58.312:ERROR / AndroidRuntime(877):在android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3599)
01-12 16:28:58.312:ERROR / AndroidRuntime(877):在android.app.ActivityThread.access $ 2300(ActivityThread.java:119)
01-12 16:28:58.312:ERROR / AndroidRuntime(877):在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1867)
01-12 16:28:58.312:ERROR / AndroidRuntime(877):在android.os.Handler.dispatchMessage(Handler.java:99)
01-12 16:28:58.312:ERROR / AndroidRuntime(877):在android.os.Looper.loop(Looper.java:123)
01-12 16:28:58.312:ERROR / AndroidRuntime(877):在android.app.ActivityThread.main(ActivityThread.java:4363)
01-12 16:28:58.312:ERROR / AndroidRuntime(877):在java.lang.reflect.Method.invokeNative(本机方法)
01-12 16:28:58.312:ERROR / AndroidRuntime(877):在java.lang.reflect.Method.invoke(Method.java:521)
01-12 16:28:58.312:ERROR / AndroidRuntime(877):在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:860)
01-12 16:28:58.312:ERROR / AndroidRuntime(877):在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
01-12 16:28:58.312:ERROR / AndroidRuntime(877):在dalvik.system.NativeStart.main(本机方法)
有没有人有任何想法,可能是什么问题?
下面是我的活动的基本骨架:
公共类ActivityFlipper扩展活动实现OnItemClickListener,OnClickListener {
ViewFlipper脚蹼;
//查询令牌
最终诠释LIST1_MY_QUERY_TOKEN = 42;
最终诠释LIST2_MY_QUERY_TOKEN = 43;
//瓦尔为List1的屏幕
私人List1Adapter mList1Adapter = NULL;
私人光标mList1Cursor = NULL;
List1QueryHandler mList1QueryHandler;
//瓦尔为list2中屏
私人List2Adapter mList2Adapter = NULL;
私人光标mList2Cursor = NULL;
List2QueryHandler mList2QueryHandler;
为List1的屏幕// UI控件
私人的ListView mList1;
私人按钮MADD;
私人TextView的mList1Header;
对于list2中屏幕// UI控件
私人的ListView mList2;
私人TextView的mList2Header;
私人按钮mSelector;
// UI控件常见
私人ProgressDialog mScannerProgress;
/ **第一次创建活动时调用。 * /
@覆盖
公共无效的onCreate(包savedInstanceState){
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
的setContentView(R.layout.layout_flipper);
//设置的鳍状肢屏幕
脚蹼=(ViewFlipper)findViewById(R.id.flipper);
//设置List1的屏幕
mList1 =(ListView控件)findViewById(R.id.list1_list);
mList1.setOnItemClickListener(本);
MADD =(按钮)findViewById(R.id.list1_add);
mAdd.setOnClickListener(本);
mList1Header =(TextView中)findViewById(R.id.list1_header);
mList1Header.setOnClickListener(新OnClickListener(){
公共无效的onClick(视图v){
flipper.setInAnimation(inFromRightAnimation());
flipper.setOutAnimation(outToLeftAnimation());
flipper.showNext();
}
});
setList1Adapter();
mList1QueryHandler =新List1QueryHandler(本);
registerForContextMenu(mList1);
registerForContextMenu(MADD);
//设置list2中屏
mList2 =(ListView控件)findViewById(R.id.list2_list);
mList2Header =(TextView中)findViewById(R.id.list2_header);
mList2Header.setOnClickListener(新OnClickListener(){
公共无效的onClick(视图v){
flipper.setInAnimation(inFromLeftAnimation());
flipper.setOutAnimation(outToRightAnimation());
flipper.show previous();
}
});
mSelector =(按钮)findViewById(R.id.list2_changestore);
mSelector.setOnClickListener(本);
setList2Adapter();
mList2QueryHandler =新List2pingQueryHandler(本);
registerForContextMenu(mList2);
}
私人无效setList1Adapter(){
mList1Adapter =新List1Adapter(ActivityList1.this,NULL);
mList1.setAdapter(mList1Adapter);
}
私人无效setList2Adapter(){
mList2Adapter =新List2Adapter(ActivityList1.this,NULL);
mList2.setAdapter(mList2Adapter);
}
@覆盖
保护无效的onPause(){
//删除广播监听器
unregisterReceiver(onBroadcast);
super.onPause();
}
@覆盖
保护无效onResume(){
super.onResume();
//将广播监听器
registerReceiver(onBroadcast,新的IntentFilter(listquery));
//如果显示出摆脱扫描进度
如果(mScannerProgress =空&安培;!&安培; mScannerProgress.isShowing()){
mScannerProgress.dismiss();
}
//获取数据来填充列表
doList1Query(假);
doList2Query(假);
}
公共无效onItemClick(适配器视图<→1,视图V,INT位置,长的id){
如果(v.getId()== mList1.getId()){
//做的东西
}
否则如果(v.getId()== mList2.getId()){
//做的东西
}
}
公共无效的onClick(视图v){
如果(v.getId()== R.id.list1_add){
//做的东西
}
否则如果(v.getId()== R.id.list2_changestore){
//做的东西
}
}
@覆盖
公共无效onActivityResult(INT申请code,INT结果code,意图数据){
//做的东西
}
光标doList1Query(布尔同步){
//取消所有待查询
mList1QueryHandler.cancelOperation(LIST1_MY_QUERY_TOKEN);
如果(同步){
尝试 {
返回getContentResolver()查询(URI,
列,
哪里,
空值,
订购);
}
赶上(UnsupportedOperationException异常前){
}
}
其他 {
setProgressBarIndeterminateVisibility(真正的);
mList1QueryHandler.startQuery(LIST1_MY_QUERY_TOKEN,
空值,
URI,
列,
哪里,
空值,
订购);
}
返回null;
}
光标doList2Query(布尔同步){
mList2QueryHandler.cancelOperation(LIST2_MY_QUERY_TOKEN);
如果(同步){
尝试 {
返回getContentResolver()查询(URI,
getDisplayColumns(),
哪里,
空值,
订购);
}
赶上(UnsupportedOperationException异常前){
}
}
其他 {
setProgressBarIndeterminateVisibility(真正的);
mList2QueryHandler.startQuery(LIST2_MY_QUERY_TOKEN,
空值,
URI,
列,
哪里,
空值,
订购);
}
返回null;
}
私人的BroadcastReceiver onBroadcast =新的BroadcastReceiver(){
@覆盖
公共无效的onReceive(上下文ctxt,意图我){
doList1Query(假);
doList2Query(假);
}
};
私人动画inFromRightAnimation(){
动画inFromRight =新TranslateAnimation(
Animation.RELATIVE_TO_PARENT,+ 1.0F,Animation.RELATIVE_TO_PARENT,0.0,
Animation.RELATIVE_TO_PARENT,0.0,Animation.RELATIVE_TO_PARENT,0.0
);
inFromRight.setDuration(500);
inFromRight.setInterpolator(新AccelerateInterpolator());
返回inFromRight;
}
私人动画outToLeftAnimation(){
动画outtoLeft =新TranslateAnimation(
Animation.RELATIVE_TO_PARENT,0.0,Animation.RELATIVE_TO_PARENT,-1.0F,
Animation.RELATIVE_TO_PARENT,0.0,Animation.RELATIVE_TO_PARENT,0.0
);
outtoLeft.setDuration(500);
outtoLeft.setInterpolator(新AccelerateInterpolator());
返回outtoLeft;
}
私人动画inFromLeftAnimation(){
动画inFromLeft =新TranslateAnimation(
Animation.RELATIVE_TO_PARENT,-1.0F,Animation.RELATIVE_TO_PARENT,0.0,
Animation.RELATIVE_TO_PARENT,0.0,Animation.RELATIVE_TO_PARENT,0.0
);
inFromLeft.setDuration(500);
inFromLeft.setInterpolator(新AccelerateInterpolator());
返回inFromLeft;
}
私人动画outToRightAnimation(){
动画outtoRight =新TranslateAnimation(
Animation.RELATIVE_TO_PARENT,0.0,Animation.RELATIVE_TO_PARENT,+ 1.0F,
Animation.RELATIVE_TO_PARENT,0.0,Animation.RELATIVE_TO_PARENT,0.0
);
outtoRight.setDuration(500);
outtoRight.setInterpolator(新AccelerateInterpolator());
返回outtoRight;
}
}
事实上,这是Android中的大便中的错误。你可以解决它通过使用SafeViewFlipper来代替:
进口android.content.Context;
进口android.util.AttributeSet;
进口android.widget.ViewFlipper;
公共类SafeViewFlipper扩展ViewFlipper {
公共SafeViewFlipper(上下文的背景下){
超(上下文);
}
公共SafeViewFlipper(上下文的背景下,ATTRS的AttributeSet){
超(背景下,ATTRS);
}
@覆盖
公共无效onDetachedFromWindow(){
尝试 {
super.onDetachedFromWindow();
}
赶上(抛出:IllegalArgumentException E){
//这种情况,当你旋转和打开键盘的同时
//其他可能的旋转相关的场景,以及
stopFlipping();
}
}
}
I originally had two ListActivity classes.
I'm experimenting with having 1 Activity and, using a ViewFlipper, flipping between the two lists.
It seems to be working great except for one problem. If I rotate the emulator, I'll randomly get a crash. It doesn't happen every time and I can't figure out a specific workflow to trigger it. This is the error:
01-12 16:28:58.292: WARN/dalvikvm(877): threadid=3: thread exiting with uncaught exception (group=0x4001b188)
01-12 16:28:58.292: ERROR/AndroidRuntime(877): Uncaught handler: thread main exiting due to uncaught exception
01-12 16:28:58.312: ERROR/AndroidRuntime(877): java.lang.IllegalArgumentException: Receiver not registered: android.widget.ViewFlipper$1@43d44458
01-12 16:28:58.312: ERROR/AndroidRuntime(877): at android.app.ActivityThread$PackageInfo.forgetReceiverDispatcher(ActivityThread.java:667)
01-12 16:28:58.312: ERROR/AndroidRuntime(877): at android.app.ApplicationContext.unregisterReceiver(ApplicationContext.java:747)
01-12 16:28:58.312: ERROR/AndroidRuntime(877): at android.content.ContextWrapper.unregisterReceiver(ContextWrapper.java:321)
01-12 16:28:58.312: ERROR/AndroidRuntime(877): at android.widget.ViewFlipper.onDetachedFromWindow(ViewFlipper.java:104)
01-12 16:28:58.312: ERROR/AndroidRuntime(877): at android.view.View.dispatchDetachedFromWindow(View.java:5835)
01-12 16:28:58.312: ERROR/AndroidRuntime(877): at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:1076)
01-12 16:28:58.312: ERROR/AndroidRuntime(877): at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:1074)
01-12 16:28:58.312: ERROR/AndroidRuntime(877): at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:1074)
01-12 16:28:58.312: ERROR/AndroidRuntime(877): at android.view.ViewRoot.dispatchDetachedFromWindow(ViewRoot.java:1570)
01-12 16:28:58.312: ERROR/AndroidRuntime(877): at android.view.ViewRoot.doDie(ViewRoot.java:2556)
01-12 16:28:58.312: ERROR/AndroidRuntime(877): at android.view.ViewRoot.die(ViewRoot.java:2526)
01-12 16:28:58.312: ERROR/AndroidRuntime(877): at android.view.WindowManagerImpl.removeViewImmediate(WindowManagerImpl.java:218)
01-12 16:28:58.312: ERROR/AndroidRuntime(877): at android.view.Window$LocalWindowManager.removeViewImmediate(Window.java:436)
01-12 16:28:58.312: ERROR/AndroidRuntime(877): at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3498)
01-12 16:28:58.312: ERROR/AndroidRuntime(877): at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3599)
01-12 16:28:58.312: ERROR/AndroidRuntime(877): at android.app.ActivityThread.access$2300(ActivityThread.java:119)
01-12 16:28:58.312: ERROR/AndroidRuntime(877): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1867)
01-12 16:28:58.312: ERROR/AndroidRuntime(877): at android.os.Handler.dispatchMessage(Handler.java:99)
01-12 16:28:58.312: ERROR/AndroidRuntime(877): at android.os.Looper.loop(Looper.java:123)
01-12 16:28:58.312: ERROR/AndroidRuntime(877): at android.app.ActivityThread.main(ActivityThread.java:4363)
01-12 16:28:58.312: ERROR/AndroidRuntime(877): at java.lang.reflect.Method.invokeNative(Native Method)
01-12 16:28:58.312: ERROR/AndroidRuntime(877): at java.lang.reflect.Method.invoke(Method.java:521)
01-12 16:28:58.312: ERROR/AndroidRuntime(877): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
01-12 16:28:58.312: ERROR/AndroidRuntime(877): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
01-12 16:28:58.312: ERROR/AndroidRuntime(877): at dalvik.system.NativeStart.main(Native Method)
Does anyone have any ideas as to what might be the problem?
Here is a basic skeleton of my Activity:
public class ActivityFlipper extends Activity implements OnItemClickListener, OnClickListener {
ViewFlipper flipper;
// query tokens
final int LIST1_MY_QUERY_TOKEN = 42;
final int LIST2_MY_QUERY_TOKEN = 43;
// vars for list1 screen
private List1Adapter mList1Adapter = null;
private Cursor mList1Cursor = null;
List1QueryHandler mList1QueryHandler;
// vars for list2 screen
private List2Adapter mList2Adapter = null;
private Cursor mList2Cursor = null;
List2QueryHandler mList2QueryHandler;
// ui controls for list1 screen
private ListView mList1;
private Button mAdd;
private TextView mList1Header;
// ui controls for list2 screen
private ListView mList2;
private TextView mList2Header;
private Button mSelector;
// ui controls common
private ProgressDialog mScannerProgress;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.layout_flipper);
// set up flipper screen
flipper = (ViewFlipper) findViewById(R.id.flipper);
// set up list1 screen
mList1 = (ListView)findViewById(R.id.list1_list);
mList1.setOnItemClickListener(this);
mAdd = (Button)findViewById(R.id.list1_add);
mAdd.setOnClickListener(this);
mList1Header = (TextView)findViewById(R.id.list1_header);
mList1Header.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
flipper.setInAnimation(inFromRightAnimation());
flipper.setOutAnimation(outToLeftAnimation());
flipper.showNext();
}
});
setList1Adapter();
mList1QueryHandler = new List1QueryHandler(this);
registerForContextMenu(mList1);
registerForContextMenu(mAdd);
// set up list2 screen
mList2 = (ListView)findViewById(R.id.list2_list);
mList2Header = (TextView)findViewById(R.id.list2_header);
mList2Header.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
flipper.setInAnimation(inFromLeftAnimation());
flipper.setOutAnimation(outToRightAnimation());
flipper.showPrevious();
}
});
mSelector = (Button)findViewById(R.id.list2_changestore);
mSelector.setOnClickListener(this);
setList2Adapter();
mList2QueryHandler = new List2pingQueryHandler(this);
registerForContextMenu(mList2);
}
private void setList1Adapter() {
mList1Adapter = new List1Adapter(ActivityList1.this, null);
mList1.setAdapter(mList1Adapter);
}
private void setList2Adapter() {
mList2Adapter = new List2Adapter(ActivityList1.this, null);
mList2.setAdapter(mList2Adapter);
}
@Override
protected void onPause() {
// remove broadcast listener
unregisterReceiver(onBroadcast);
super.onPause();
}
@Override
protected void onResume() {
super.onResume();
// add broadcast listener
registerReceiver(onBroadcast, new IntentFilter("listquery"));
// get rid of scanner progress if showing
if (mScannerProgress != null && mScannerProgress.isShowing()) {
mScannerProgress.dismiss();
}
// get data to populate lists
doList1Query(false);
doList2Query(false);
}
public void onItemClick(AdapterView<?> l, View v, int position, long id) {
if (v.getId() == mList1.getId()) {
// do stuff
}
else if (v.getId() == mList2.getId()) {
// do stuff
}
}
public void onClick(View v) {
if (v.getId() == R.id.list1_add) {
// do stuff
}
else if (v.getId() == R.id.list2_changestore) {
// do stuff
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
// do stuff
}
Cursor doList1Query(boolean sync) {
// Cancel any pending queries
mList1QueryHandler.cancelOperation(LIST1_MY_QUERY_TOKEN);
if (sync) {
try {
return getContentResolver().query(uri,
columns,
where,
null,
order);
}
catch (UnsupportedOperationException ex) {
}
}
else {
setProgressBarIndeterminateVisibility(true);
mList1QueryHandler.startQuery(LIST1_MY_QUERY_TOKEN,
null,
uri,
columns,
where,
null,
order);
}
return null;
}
Cursor doList2Query(boolean sync) {
mList2QueryHandler.cancelOperation(LIST2_MY_QUERY_TOKEN);
if (sync) {
try {
return getContentResolver().query(uri,
getDisplayColumns(),
where,
null,
order);
}
catch (UnsupportedOperationException ex) {
}
}
else {
setProgressBarIndeterminateVisibility(true);
mList2QueryHandler.startQuery(LIST2_MY_QUERY_TOKEN,
null,
uri,
columns,
where,
null,
order);
}
return null;
}
private BroadcastReceiver onBroadcast = new BroadcastReceiver() {
@Override
public void onReceive(Context ctxt, Intent i) {
doList1Query(false);
doList2Query(false);
}
};
private Animation inFromRightAnimation() {
Animation inFromRight = new TranslateAnimation(
Animation.RELATIVE_TO_PARENT, +1.0f, Animation.RELATIVE_TO_PARENT, 0.0f,
Animation.RELATIVE_TO_PARENT, 0.0f, Animation.RELATIVE_TO_PARENT, 0.0f
);
inFromRight.setDuration(500);
inFromRight.setInterpolator(new AccelerateInterpolator());
return inFromRight;
}
private Animation outToLeftAnimation() {
Animation outtoLeft = new TranslateAnimation(
Animation.RELATIVE_TO_PARENT, 0.0f, Animation.RELATIVE_TO_PARENT, -1.0f,
Animation.RELATIVE_TO_PARENT, 0.0f, Animation.RELATIVE_TO_PARENT, 0.0f
);
outtoLeft.setDuration(500);
outtoLeft.setInterpolator(new AccelerateInterpolator());
return outtoLeft;
}
private Animation inFromLeftAnimation() {
Animation inFromLeft = new TranslateAnimation(
Animation.RELATIVE_TO_PARENT, -1.0f, Animation.RELATIVE_TO_PARENT, 0.0f,
Animation.RELATIVE_TO_PARENT, 0.0f, Animation.RELATIVE_TO_PARENT, 0.0f
);
inFromLeft.setDuration(500);
inFromLeft.setInterpolator(new AccelerateInterpolator());
return inFromLeft;
}
private Animation outToRightAnimation() {
Animation outtoRight = new TranslateAnimation(
Animation.RELATIVE_TO_PARENT, 0.0f, Animation.RELATIVE_TO_PARENT, +1.0f,
Animation.RELATIVE_TO_PARENT, 0.0f, Animation.RELATIVE_TO_PARENT, 0.0f
);
outtoRight.setDuration(500);
outtoRight.setInterpolator(new AccelerateInterpolator());
return outtoRight;
}
}
Indeed this is a bug in the bowels of Android. You can work around it by using a "SafeViewFlipper" instead:
import android.content.Context;
import android.util.AttributeSet;
import android.widget.ViewFlipper;
public class SafeViewFlipper extends ViewFlipper {
public SafeViewFlipper(Context context) {
super(context);
}
public SafeViewFlipper(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public void onDetachedFromWindow() {
try {
super.onDetachedFromWindow();
}
catch (IllegalArgumentException e) {
// This happens when you're rotating and opening the keyboard that the same time
// Possibly other rotation related scenarios as well
stopFlipping();
}
}
}
这篇关于崩溃时使用ViewFlipper旋转活动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!