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();
        }
    }

}

每个片段都应该连接到 Internet 并获取数据,但是在此之前它们应该调用接口。我为一个类编写了以下代码(其他片段的代码是这样的)。

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);
    }

主屏幕.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

问题是有时 Fragment 的寿命比它的 Activity 长,例如,如果 Activity 有配置更改(例如旋转),那么 Activity 被销毁,但 Fragment 可以保持活动状态,然后重新附加到新的(旋转的)Activity . 请参阅这篇文章: Android Fragment 生命周期超过方向更改

因此,您可能对使用 Wea​​kReference 提出的解决方案有疑问,因为在轮换之后,您将获得对旧 Activity 的引用(或者可能什么也没有)。

虽然我不确定为什么线路在 onAttach() 中崩溃,但应该没问题。

什么似乎对我有用:

1) 当我需要 Activity 的引用时,调用 getActivity()。在 onPostExecute() 中执行此操作。

2) 检查结果是否为空(这可能发生:片段的寿命可能比它们的活动长)

3) 检查活动是否为 isFinishing()——你不想在那种状态下做某些 UI 事情。

4)将活动转换为您的界面类型。

5) 调用 showProgressBar()。

于 2012-10-27T14:02:08.447 回答