本文為原創文章,歡迎轉載,但請注明出處http://www.cnblogs.com/yexiubiao/archive/2012/05/17/2506394.html
,未在文章頁面明顯位置給出原文連接的,將保留追究法律責任的權利。
昨天朋友的android項目里出現了一個Bug,剛好我有時間,就幫他看了下。
在他的項目中有個Button,點擊后彈出一個自定義的對話框,如果這時候按back鍵結束對話框,再次點擊Button打開此對話框時,就出現了以下異常:
The specified child already has a parent. You must call removeView() on the child's parent first
大概意思為:這個指定的孩子已經有一個父親了,你必須首先在該孩子的父親處調用removeView() 方法。
出錯的代碼如下:
1 case R.id.set: 2 LocalActivityManager manager = getLocalActivityManager(); 3 Intent intent = new Intent(PersonalActivity.this, SettingActivity.class); 4 View settingView = manager.startActivity("SettingActivity", intent).getDecorView(); 5 AlertDialog.Builder set_builder = new AlertDialog.Builder(PersonalActivity.this); 6 set_builder.setView(settingView); 7 set_builder.show(); /這一行報錯 8 break;
照着異常信息的提示,打算去調用removeView() ,但是找遍了所有地方都沒找到removeView() 這個方法,沒辦法只好從其他地方入手。
在這個自定義對話框中,他的View(即settingView)是通過LocalActivityManager 將SettingActivity轉換過來的,然后再通過調用set_builder.setView(settingView);將該settingView和對話框綁定在了一起,那么很顯然父親就是set_builder,孩子就是settingView。按照異常信息來說,第二次打開對話框的時候,settingView又被重新指定了一個新的父親,即第二次調用set_builder.setView(settingView);的時候,參數settingView跟上一次是同一個對象。難道是說第二次執行以上代碼時,settingView沒有被重新生成?
於是看了一下manager.startActivity)方法的注釋:
Start a new activity running in the group. Every activity you start must have a unique string ID associated with it -- this is used to keep track of the activity, so that
if you later call startActivity() again on it the same activity object will be retained.
When there had previously been an activity started under this id, it may either be destroyed and a new one started, or the current one re-used, based on these conditions, in order:
該方法startActivity()會傳入一個唯一的id,當下次再調用此方法時,如果id是一樣的,那么還是會返回相同的activity對象。所以第二次生成的settingView 復用了原來的view,導致同一個settingView 被指定多個父親。
解決方法1:
manager.removeAllActivities(); //加上這句代碼即可
View settingView = manager.startActivity("SettingActivity", intent).getDecorView();
解決方法2:(設置Intent對象的Flag----FLAG_ACTIVITY_CLEAR_TOP)
Intent intent = new Intent(PersonalActivity.this, SettingActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); //加上此行代碼即可
關於“FLAG_ACTIVITY_CLEAR_TOP”可參考
http://hi.baidu.com/fenghuang1207/item/63e9b2df0683624cddf9be8a