Android 如何在片段中实例化接口?

Android 如何在片段中实例化接口?,android,interface,fragment,instantiation,Android,Interface,Fragment,Instantiation,在我的Android应用程序中,我有一个带有progressbar的片段活动。当任何片段调用接口时,此进度条设置为可见。因此,fragment类的代码如下所示: public class MainScreen extends FragmentActivity { public interface OnConnectingToInternet { public void showProgressbar(boolean flag); } // rest o

在我的Android应用程序中,我有一个带有progressbar的片段活动。当任何片段调用接口时,此进度条设置为可见。因此,fragment类的代码如下所示:

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并获取数据,但在此之前它们应该调用接口。我为一个类编写了以下代码(其他片段的代码如下)

公共类TopRecipesFragment扩展了片段{
连接到Internet的专用网络连接到Internet;
@凌驾
公共事务主任(活动){
超级转速计(活动);
//onConnectingToInternet=(onConnectingToInternet)活动;
Log.i(标签,“连接到活动的片段”);
}
@凌驾
已创建ActivityState上的公共无效(Bundle savedInstanceState){
super.onActivityCreated(savedInstanceState);
新建MyAsyncTask.execute();
}
公共类MyAsyncTask扩展了AsyncTask{
@凌驾
受保护的void onPreExecute(){
i(标记“myAsyncTask即将启动…”);
onConnectingToInternet.showProgressbar(true);
}
@凌驾
受保护的布尔doInBackground(Void…params){
...
}
@凌驾
受保护的void onPostExecute(布尔结果){
i(标记“myAsyncTask即将启动…”);
onConnectingToInternet.showProgressbar(false);
}
} 
问题是我不知道如何实例化这个接口。如果我不将
onConnectingToInternet=(onConnectingToInternet)活动;
,那么在运行应用程序后,它将在
NullPointerException
中崩溃

但是,如果我这样实例化,那么应用程序会因为强制转换问题而崩溃。我也不能以正常的方式实例化它,比如
onConnectingToInternet=newmainscreen();


解决方案是什么?如果您有任何建议,我们将不胜感激。谢谢您,我将写信告诉您,您正在尝试以下方法:

OnConnectionToInternet.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);
            }
       }
} 
公共类TopRecipesFragment扩展了片段{
@凌驾
公共事务主任(活动){
超级转速计(活动);
Log.i(标签,“连接到活动的片段”);
}
@凌驾
已创建ActivityState上的公共无效(Bundle savedInstanceState){
super.onActivityCreated(savedInstanceState);
新建MyAsyncTask((OnConnectionToInternet)getActivity()).execute();
}
//使类为静态以避免内存泄漏
公共静态类MyAsyncTask扩展了AsyncTask{
//保持对接口的WeakReference以避免内存泄漏
私有最终WeakReference connectionRef;
MyAsyncTask(OnConnectingToInternet连接){
connectionRef=新的WeakReference(连接);
}
@凌驾
受保护的void onPreExecute(){
i(标记“myAsyncTask即将启动…”);
OnConnectionToInternetConnection=connectionRef.get();
if(null!=连接){
连接。showProgressbar(true);
}
}
@凌驾
受保护的布尔doInBackground(Void…params){
...
}
@凌驾
受保护的void onPostExecute(布尔结果){
i(标记“myAsyncTask即将启动…”);
OnConnectionToInternetConnection=connectionRef.get();
if(null!=连接){
连接。showProgressbar(假);
}
}
} 

问题在于,有时片段的寿命比其活动的寿命长,例如,如果活动有配置更改(如旋转),则活动将被销毁,但片段可以保持活动状态,然后重新连接到新的(旋转的)活动。请参阅本文:

因此,您可能会对使用WeakReference的建议解决方案有问题,因为在循环之后,您将有一个对旧活动的引用(或者可能什么都没有)

虽然我不确定为什么线路在onAttach()中崩溃,但这应该是可以的

似乎对我有用的是:

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

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

3) 检查活动是否正在完成()–您不希望在该状态下执行某些UI操作

4) 将活动强制转换为接口类型


5) 调用showProgressBar()。

哇,谢谢Sandstar。这正是我要找的东西。有一个问题,我可以将MyAsyncTask类中编写的大部分代码重新定位到onActivityCreated()方法吗?我想总结一下。谢谢,这是可能的,但是你可能需要使MyAsyncTask不是静态的,这不是很好。
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);
            }
       }
}