2

私の Android アプリケーションには、プログレスバーを持つフラグメント アクティビティがあります。この進行状況バーは、フラグメントがインターフェイスを呼び出すときに表示されるように設定されます。したがって、フラグメント クラスのコードは次のようになります。

public class MainScreen extends FragmentActivity {

    public interface OnConnectingToInternet {
        public void showProgressbar(boolean flag);
    }

    // rest of codes
    .
    .
    .

    // Implementing Interface
    public void showProgressbar(boolean flag) {
        if(flag){
            myProgressbar.showProgressBar();
        } else {
            myProgressbar.hideProgressBar();
        }
    }

}

各フラグメントはインターネットに接続してデータを取得する必要がありますが、その前にインターフェイスを呼び出す必要があります。あるクラスに対して次のコードを書きました (他のフラグメントのコードはこのようなものです)。

public class TopRecipesFragment extends Fragment {

    private OnConnectingToInternet onConnectingToInternet;


    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);

        // onConnectingToInternet = (OnConnectingToInternet) activity;

        Log.i(TAG, "Fragment attached to activity.");
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        New MyAsyncTask.execute();
    }

    public class MyAsyncTask extends AsyncTask<Void, Void, Boolean> {       

        @Override
            protected void onPreExecute() {
            Log.i(TAG, "myAsyncTask is about to start...");

            onConnectingToInternet.showProgressbar(true);
            }

        @Override
            protected Boolean doInBackground(Void... params) {
            ...
            }

        @Override
            protected void onPostExecute(Boolean result) {
            Log.i(TAG, "myAsyncTask is about to start...");

            onConnectingToInternet.showProgressbar(false);
            }

} 

問題は、このインターフェイスをインスタンス化する方法がわからないことです。を入れないonConnectingToInternet = (OnConnectingToInternet) activity;と、アプリケーションを実行した後、 でクラッシュしますNullPointerException

しかし、そのようにインスタンス化すると、キャストの問題でアプリケーションがクラッシュします。のように、通常の方法でもインスタンス化できませんonConnectingToInternet = new MainScreen();

解決策は何ですか?任意の提案をいただければ幸いです。ありがとう

4

2 に答える 2

4

私はあなたが次のようにしようとしていると書きます:

OnConnectingToInternet.java:

public interface OnConnectingToInternet {
        public void showProgressbar(boolean flag);
    }

MainScreen.java:

public class MainScreen extends FragmentActivity implements OnConnectingToInternet {


// rest of codes
.
.
.

// Implementing Interface
@Override
public void showProgressbar(boolean flag) {
    if(flag){
        myProgressbar.showProgressBar();
    } else {
        myProgressbar.hideProgressBar();
    }
}
}

TopRecipesFragment.java:

public class TopRecipesFragment extends Fragment {

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        Log.i(TAG, "Fragment attached to activity.");
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        new MyAsyncTask((OnConnectingToInternet)getActivity()).execute();
    }

    // Make class static to avoid memory leaks
    public static class MyAsyncTask extends AsyncTask<Void, Void, Boolean> {

        // Keep WeakReference to the interface to avoid memory leaks
        private final WeakReference<OnConnectingToInternet> connectionRef;       

        MyAsyncTask(OnConnectingToInternet connection) {
            connectionRef = new WeakReference<OnConnectingToInternet>(connection);
        }

        @Override
        protected void onPreExecute() {
            Log.i(TAG, "myAsyncTask is about to start...");

            OnConnectingToInternet connection = connectionRef.get();

            if (null != connection) {
               connection.showProgressbar(true);
            }
        }

        @Override
        protected Boolean doInBackground(Void... params) {
            ...
        }

        @Override
        protected void onPostExecute(Boolean result) {
            Log.i(TAG, "myAsyncTask is about to start...");

            OnConnectingToInternet connection = connectionRef.get();

            if (null != connection) {
               connection.showProgressbar(false);
            }
       }
} 
于 2012-07-24T03:21:48.363 に答える
1

問題は、フラグメントがそのアクティビティよりも長く存続する場合があることです。たとえば、アクティビティに構成の変更 (ローテーションなど) がある場合、アクティビティは破棄されますが、フラグメントは存続し、新しい (ローテーションされた) アクティビティに再接続できます。 . この投稿を参照してください: 向きの変更に対する Android フラグメントのライフサイクル

そのため、WeakReference を使用して提案されたソリューションに問題がある可能性があります。これは、ローテーション後に古いアクティビティへの参照がある (または何もない) ためです。

onAttach() で回線がクラッシュした理由はわかりませんが、問題はなかったはずです。

私にとってうまくいくように見えるもの:

1) アクティビティへの参照が必要な場合は、getActivity() を呼び出します。onPostExecute() でこれを正しく行います。

2) null の結果を確認します (これが発生する可能性があります: フラグメントはアクティビティよりも長く存続する可能性があります)。

3) アクティビティ isFinishing() かどうかを確認します – その状態で特定の UI 操作を実行したくない場合。

4) アクティビティをインターフェイス タイプにキャストします。

5) showProgressBar() を呼び出します。

于 2012-10-27T14:02:08.447 に答える