所以采用这里描述的设计模式,其中异步任务通过setRetainInstance包裹保留的片段,如此处所述
http://www.androiddesignpatterns.com/2013/04/retaining-objects-across-config-changes.html
我遇到的问题是,在工作者片段可以附加到活动之前启动任务,同时将mCallBack保持为null,同时调用onPreExecute,这将抛出nullPointerException /
这很大程度上是因为异步任务是通过方法调用(一个创建内部异步任务实例的启动方法)而不是在onCreate或OnActivityCreated中启动的,因为任务可以再次启动(在它的新实例)并且无法在onCreate或OnActivity中创建,因为这些方法的生命周期只调用1次,因为我知道setRetainInstance。
我的问题是在哪里编程某种例程,等待片段附加到活动例程,如果是这样,你需要做什么?
非常感谢。
Update1:已发布代码
这是工作片段的添加方式。当用户按下发送反馈按钮时。调用此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
}
}
工人碎片启动任务方法
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;
}
工作人员片段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;
}
答案 0 :(得分:0)
所以我提出了一个解决问题的解决方案。可能不是最佳解决方案,但我的问题似乎已得到解决。
我在我的界面上添加了一个名为onThreadFragmentAttached()
的回调public static interface ResultAsyncTaskCallbacks
{
void onPreExecuteResults();
void onCancelledResults();
void onPostExecuteResults();
void onThreadFragmentAttached();
}
我在工作片段
中添加了一个类变量private boolean isFirstTime=true;
这个布尔值在开始时表示该片段是第一次添加
在OnActivityCreated中我可以安全地假设该片段是附加的,因为这就是该方法所代表的含义。
有这个逻辑。检查firstTime是否为true(是的,如果第一次添加片段,则为yes)。如果调用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()开始;