0

アクティビティ グループを使用しようとしています。タブを使用しているため、ロード時にタブを表示し、リスト アイテムをクリックした後にアクティビティを表示したいからです。しかし、次の行で nullpointerexception が発生しています。

View view1 = S1_Group.group.getLocalActivityManager()
                           .startActivity("S1", intent)
                           .getDecorView();

コードは.. .

lv.setOnItemClickListener(new OnItemClickListener() {
    public void onItemClick(AdapterView<?> parent, View view,
          int position, long id) {


        Intent intent = new Intent(getApplicationContext(), S1.class);

        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        Log.d("test","Before view");
        try{
            View view1 = S1_Group.group.getLocalActivityManager()
               .startActivity("S1", intent)
               .getDecorView();
               Settings_Group.group.setContentView(view1);      
        }
        catch (Exception e){
            Log.e("test","view failded:"+e);
        }
....

更新: これが私のグループ活動の様子です: 何が問題なのかわかりませんでした.,

public class S1_Group extends ActivityGroup {

    public static S1_Group group;
    private ArrayList<View> history;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        this.history = new ArrayList<View>();
        group = this;

        View view = getLocalActivityManager().startActivity("F1", 
                new Intent(this, F1.class).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)).getDecorView();

        setContentView(view);
    }
}
4

3 に答える 3

1

私も同じ問題を抱えていました。それを解決するために、最初の回答が示唆したように、マルチコール行を 3 行に分解しました。

            LocalActivityManager processManager =activityGroup.group.getLocalActivityManager();
            Window w = processManager.startActivity("ActivityOne", myIntent);
            View view = w.getDecorView();

その後、最初の行が問題であることがわかりました。アクティビティ グループ外のアクティビティ (別のタブのアクティビティ) から ActivityOne を呼び出しているため、静的な "activityGroup.group...." はまだ初期化されていません。したがって、インテントを起動する前に、そのタブに切り替えてからこのタブに戻るというかなり厄介な修正があります。したがって、上記のコードの直前に次を追加します。

            AppName.switchToTab(2);  
            AppName.switchToTab(1); 

これでうまくいき、タブスイッチが見えなくなりました。よりきちんとした解決策は、起動時にすべてのタブに切り替えて、それらがすべて初期化されていることを確認することです...

于 2011-03-23T15:58:36.807 に答える
1

同じ問題に遭遇し、以前に破棄されたアクティビティと同じ ID でアクティビティを (再) 開始しようとしたときに発生する LocalActivityManager のバグがある (またはあった) ようです。destroyActivity メソッド内のバグのため、単に Window として null を返します。私が使用している回避策は、リフレクションを使用してアクティビティを適切に破棄します(回避策の後の詳細な説明):

public boolean destroyActivityWorkAround(String id) {
    final LocalActivityManager activityManager = getLocalActivityManager();
    if(activityManager != null){
        activityManager.destroyActivity(id, false);             
        try {
            // Use reflection to get to the HashMaps with the records(which activities are started ect.)
            // to remove the records properly 
            // http://code.google.com/p/android/issues/detail?id=10083
            final Field mActivitiesField = LocalActivityManager.class.getDeclaredField("mActivities");
            if(mActivitiesField != null){
                mActivitiesField.setAccessible(true);
                @SuppressWarnings("unchecked")
                final Map<String, Object> mActivities = (Map<String, Object>)mActivitiesField.get(activityManager);
                if(mActivities != null){
                    mActivities.remove(id);
                }
                final Field mActivityArrayField = LocalActivityManager.class.getDeclaredField("mActivityArray");
                if(mActivityArrayField != null){
                    mActivityArrayField.setAccessible(true);
                    @SuppressWarnings("unchecked")
                    final ArrayList<Object> mActivityArray = (ArrayList<Object>)mActivityArrayField.get(activityManager);
                    if(mActivityArray != null){
                        for(Object record : mActivityArray){
                            final Field idField = record.getClass().getDeclaredField("id");
                            if(idField != null){
                                idField.setAccessible(true);
                                final String _id = (String)idField.get(record);
                                if(id.equals(_id)){
                                    mActivityArray.remove(record);
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            Log.e(LOGTAG, this.getClass().getSimpleName() + ".destroyActivityWorkAround() removing activity using reflection failed with error:", e);
            //e.printStackTrace();
        }
        return true;
    }
    return false;
}

LocalActivityManager.destroyActivity(...) にはいくつかの API バージョンのバグが含まれているため、これは回避策です。このメソッドは、Activity をその HashMap ( LocalActivityManager の source )から適切に削除しません。

     public Window destroyActivity(String id, boolean finish) {
         LocalActivityRecord r = mActivities.get(id);   //<-- id's are the key's for the HashMap
         Window win = null;
         if (r != null) {
             win = performDestroy(r, finish);
             if (finish) {
                    mActivities.remove(r);  //--> This works on id's not the 'r object', this doesn't remove anything
             }
         }
         return win;
     } 

破棄されるアクティビティの LocalActivityRecord を削除するには、次の if(finish) ステートメントに従う必要があります。

if (finish) {
    mActivities.remove(id);    //--> mActivities should remove the id
    mActivityArray.remove(r);  //--> mActivitiesArray should remove the 'r object' (LocalActivityRecord)
}

彼らはFroyoで修正されていると言っていますが、2.3.3を実行しているSamsung galaxy S2でまだ遭遇しました

于 2011-10-04T14:26:23.943 に答える
0

ActivityGroup をどのように実装したかはわかりませんが、グループは静的変数である必要があります。

Google でこのチュートリアルを見つけ、ActivityGroup の実装方法について説明しています。 http://blog.henriklarsentoft.com/2010/07/android-tabactivity-nested-activities/

これが役に立てば幸いです、トバイアス

于 2011-02-06T11:05:29.357 に答える