【问题标题】:Android: Is There A Way To Wait Until A Fragment Attaches To An Activity?Android:有没有办法等到片段附加到活动?
【发布时间】:2014-10-22 23:30:23
【问题描述】:

因此采用此处描述的设计模式,其中异步任务通过此处描述的 setRetainInstance 包裹在保留的片段周围

http://www.androiddesignpatterns.com/2013/04/retaining-objects-across-config-changes.html

我遇到了一个问题,即在工作片段可以附加到活动之前启动任务,同时调用 onPreExecute 时将 mCallBack 设为空,这会引发 nullPointerException/

这主要是因为异步任务是通过方法调用(创建内部异步任务实例的 start 方法)而不是在 onCreate 或 OnActivityCreated 中启动的,因为任务可以再次启动(在它的新实例)并且不能在创建的 onCreate 或 OnActivity 中这样做,因为据我所知,这些方法的生命周期仅调用 1 次,因为 setRetainInstance 。

我的问题是在哪里编写某种例程的方法,从而等待片段附加到活动例程,如果是这样,您需要执行的任务是什么?

非常感谢。

更新 1:已发布代码

这是添加工作片段的方式。当用户按下发送反馈按钮时。调用此 OnClick 侦听器。您看到的最后一个 if 语句是启动异步任务的原因。请注意,此代码在另一个片段中。

@Override
public void onClick(View v) 
{
    // TODO Auto-generated method stub
    FragmentManager fm = getActivity().getSupportFragmentManager();

    mThreadFragment = (ConnectToServerForResults) fm.findFragmentByTag(ConnectToServerForResults.class.getName());

    if(mThreadFragment == null)
    {
        mThreadFragment = new ConnectToServerForResults();
        fm.beginTransaction().add(mThreadFragment, ConnectToServerForResults.class.getName()).commit();
    }


    if(!mThreadFragment.isRunning())
    {
        mThreadFragment.startSendFeedBack(3, preventSQLInjections(),getResources().getString(R.string.app_name));
    }
    else
    {
                //Work in progress :D
    }

}

Worker Fragment 启动任务方法

public void startSendFeedBack(int requestCode,String feedback,String appName)
{
    XAMPP_URL ="http://10.0.2.2/testStuff/feed.php";
    http = new HTTPConnection();
    http.execute(String.valueOf(requestCode),XAMPP_URL,feedback,appName);
    mRunning = true;
}

Worker Fragment OnAttach

@Override
    public void onAttach(Activity activity) 
    {
        // TODO Auto-generated method stub
        super.onAttach(activity);
        Log.d("ERSEN", "onAttach");
        if(!(activity instanceof ResultAsyncTaskCallbacks))
        {
            throw new IllegalStateException("activity must implement the AsyncTaskCallbacks interface.");
        }

        mCallback = (ResultAsyncTaskCallbacks) activity;



    }

【问题讨论】:

  • 您发布的文章中针对 mCallbacks 的所有方法调用都被空检查包围。你是如何得到 NullPointerException 的?另外,您如何以及在哪里开始后台任务?您可以在 TaskFragment 中添加一些逻辑,以确保任务仅在调用 onAttach 后启动。
  • 你能发布一些代码吗?如何启动异步任务以及如何将片段添加到活动中?
  • 嗨。我添加了一些代码。 @Karakuri,我没有围绕 mCallbacks 被调用的空检查。
  • @Karakuri,您能否向我解释一下您提到的逻辑,我可以在 myTaskFragment 中添加以确保任务仅在调用 onAttach 后开始
  • 使用布尔值isAttached,在onAttach 中设置为true,在onDetach 中设置为false。制作另一个布尔值pending。当您告诉片段开始工作时,如果isAttached 为假,则将pending 设置为真。在下一次附加时,如果pending 为真,则启动任务并将pending 设置为假。

标签: android android-fragments


【解决方案1】:

所以我提出了解决问题的解决方案。可能不是最好的解决方案,但我的问题似乎已解决。

我向我的接口添加了一个回调,称为 onThreadFragmentAttached()

public static interface ResultAsyncTaskCallbacks
{
    void onPreExecuteResults();
    void onCancelledResults();
    void onPostExecuteResults();
    void onThreadFragmentAttached();
}

我在工作片段中添加了一个类变量

private boolean isFirstTime=true;

开头的这个布尔值表示片段是第一次添加

在 OnActivityCreated 中,我可以安全地假设片段已附加,因为这是该方法所表示的。

里面有这个逻辑。检查 firstTime 是否为真(如果是第一次添加片段,则为真)。如果调用 onThreadFragmentAttached();。将 firstTime 设置为 false,因为添加了片段。这个错误是通过配置更改保留的,因为这个片段被保留了。

if(isFirstTime == true)
{
    mCallback.onThreadFragmentAttached();
    isFirstTime = false;
}

在实现回调的主要活动中

@Override
    public void onThreadFragmentAttached(int fragmentCode) 
    {
        FB = (FeedBack)fragmentManger.findFragmentByTag(FeedBack.class.getName());
    FB.sendFeedback();
}

找到反馈片段(这是我需要启动任务的片段)并调用 sendFeedBack 方法。

这是简单调用start方法的方法。

public void sendFeedback()
    {
        mThreadFragment.startSendFeedBack(3, preventSQLInjections(),getResources().getString(R.string.app_name));
    }

在我的 onClick 中,我有以下逻辑

//Check if there is not a task running at the moment
        if(!mThreadFragment.isRunning()) //No task
        {
            //if its the first time worker fragment is being added it will start the task itself via the onThreadFragmentAttached callback (inside main activity) which then calls the sendFeedBack method that starts the task
            if(mThreadFragment.getIsFirstTime() != true) //this is here in cases where the thread fragment is already attached and the task can be started as normal.
            {
                sendFeedback();
            }   
        }

这会检查片段是否已经被添加并且只是为了继续并开始任务。注意 getIsFirstTime 方法只返回类变量 isFirstTime 的值。如果它的错误继续正常进行,因为它已经附加。如果是真的,这将被绕过,任务将通过 onThreadAttachedCallback() 开始;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-24
    • 1970-01-01
    • 1970-01-01
    • 2021-09-02
    相关资源
    最近更新 更多