Java 屏幕旋转后,碎片管理器中没有目标
我一直在关注Alex Lockwood 2013的本教程,了解如何在配置更改后向新活动实例生成线程报告 在我尝试在嵌套片段中执行此操作之前,一切都很顺利。基本上,活动添加片段A,片段A被片段B替换,片段B内部启动异步任务线程 然而,如果我通过Backback返回片段A,然后尝试旋转,我会得到标题中所述的以下异常 这是密码 主要活动 片段A 片段B 螺纹碎片Java 屏幕旋转后,碎片管理器中没有目标,java,android,multithreading,android-fragments,Java,Android,Multithreading,Android Fragments,我一直在关注Alex Lockwood 2013的本教程,了解如何在配置更改后向新活动实例生成线程报告 在我尝试在嵌套片段中执行此操作之前,一切都很顺利。基本上,活动添加片段A,片段A被片段B替换,片段B内部启动异步任务线程 然而,如果我通过Backback返回片段A,然后尝试旋转,我会得到标题中所述的以下异常 这是密码 主要活动 片段A 片段B 螺纹碎片 不确定这是否可行,但您可能需要添加以下代码行: setRetainInstance(true) 在片段的onViewCreated方法中
不确定这是否可行,但您可能需要添加以下代码行:
setRetainInstance(true)
在片段的onViewCreated方法中
您还在片段A中向backbackback添加null,因此这可能也是一个问题 嗨,我在线程片段的onCreate方法中有setRetainInstancetrue行。不过我还是在onCreateView上试过了。backback的参数是可选的,它只是一个标记,如果需要,它可以为null。我不认为这会导致任何问题,我在许多教程中看到它为空/您可能应该将该行添加到所有片段中。好吧,我不知道。嗨,你找到解决办法了吗?我有同样的问题…可能是重复的
public class FragmentA extends Fragment implements OnClickListener
{
private Button GoToFragmentB;
private ViewGroup container;
@Override
public View onCreateView(LayoutInflater inflater,ViewGroup container, Bundle savedInstanceState)
{
// TODO Auto-generated method stub
View view = inflater.inflate(R.layout.fragment_a, container, false);
this.container = container;
GoToFragmentB = (Button)view.findViewById(R.id.bGoToFragmentB);
GoToFragmentB.setOnClickListener(this);
return view;
}
@Override
public void onClick(View v)
{
// TODO Auto-generated method stub
FragmentManager fragmentManager = getFragmentManager();
FragmentB fb = new FragmentB();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(container.getId(), fb, FragmentB.class.getName());
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
}
public class FragmentB extends Fragment implements OnClickListener, ThreadFragment.AsyncTaskCallbacks{
private ThreadFragment mThreadFragment;
private ProgressBar progress_horizontal;
private TextView percent_progress;
private Button task_button;
private static final String KEY_CURRENT_PROGRESS = "current_progress";
private static final String KEY_PERCENT_PROGRESS = "percent_progress";
@Override
public View onCreateView(LayoutInflater inflater,ViewGroup container, Bundle savedInstanceState) {
// TODO Auto-generated method stub
View view = inflater.inflate(R.layout.fragment_b, container, false);
progress_horizontal = (ProgressBar) view.findViewById(R.id.progress_horizontal);
percent_progress = (TextView)view.findViewById(R.id.percent_progress);
task_button = (Button)view.findViewById(R.id.task_button);
task_button.setOnClickListener(this);
return view;
}
@Override
public void onActivityCreated(Bundle savedInstanceState)
{
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
if(savedInstanceState != null)
{
progress_horizontal.setProgress(savedInstanceState.getInt(KEY_CURRENT_PROGRESS));
percent_progress.setText(savedInstanceState.getString(KEY_PERCENT_PROGRESS));
}
FragmentManager fm = getActivity().getSupportFragmentManager();
mThreadFragment = (ThreadFragment) fm.findFragmentByTag(ThreadFragment.class.getName());
if(mThreadFragment == null)
{
mThreadFragment = new ThreadFragment();
mThreadFragment.setTargetFragment(this, 0);
fm.beginTransaction().add(mThreadFragment, ThreadFragment.class.getName()).commit();
}
if(mThreadFragment.isRunning() == true)
{
task_button.setText(getString(R.string.cancel));
}
else
{
task_button.setText(getString(R.string.start));
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
// TODO Auto-generated method stub
super.onSaveInstanceState(outState);
outState.putInt(KEY_CURRENT_PROGRESS, progress_horizontal.getProgress());
outState.putString(KEY_PERCENT_PROGRESS, percent_progress.getText().toString());
}
@Override
public void onClick(View v)
{
// TODO Auto-generated method stub
if(mThreadFragment.isRunning() == true)
{
mThreadFragment.cancel();
}
else
{
mThreadFragment.start();
}
}
@Override
public void onPreExecute()
{
// TODO Auto-generated method stub
task_button.setText(getString(R.string.cancel));
Toast.makeText(getActivity(), R.string.task_started_msg, Toast.LENGTH_SHORT).show();
}
@Override
public void onProgressUpdate(int percent)
{
// TODO Auto-generated method stub
progress_horizontal.setProgress(percent * progress_horizontal.getMax() / 100);
percent_progress.setText(percent + "%");
}
@Override
public void onCancelled()
{
// TODO Auto-generated method stub
task_button.setText("Start");
progress_horizontal.setProgress(0);
percent_progress.setText("0%");
}
@Override
public void onPostExecute()
{
// TODO Auto-generated method stub
task_button.setText(getString(R.string.start));
progress_horizontal.setProgress(progress_horizontal.getMax());
percent_progress.setText(getString(R.string.one_hundred_percent));
Toast.makeText(getActivity(), R.string.task_complete_msg, Toast.LENGTH_SHORT).show();
}
@Override
public void onPause() {
// TODO Auto-generated method stub
mThreadFragment.pause();
super.onPause();
}
@Override
public void onResume() {
// TODO Auto-generated method stub
mThreadFragment.resume();
super.onResume();
}
}
public class ThreadFragment extends Fragment {
static interface AsyncTaskCallbacks
{
void onPreExecute();
void onProgressUpdate(int percent);
void onCancelled();
void onPostExecute();
}
private AsyncTaskCallbacks mCallback;
private boolean mRunning;
private boolean isPause;
private TestTask mTask;
@Override
public void onAttach(Activity activity) {
// TODO Auto-generated method stub
super.onAttach(activity);
if(!(getTargetFragment() instanceof AsyncTaskCallbacks))
{
throw new IllegalStateException("Target fragment must implement the AsyncTaskCallbacks interface.");
}
if(getTargetFragment() != null)
{
mCallback = (AsyncTaskCallbacks) getTargetFragment();
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
cancel();
}
public void start()
{
if(mRunning == false)
{
mTask = new TestTask();
mTask.execute();
mRunning = true;
}
}
public void cancel()
{
if(mRunning == true)
{
mTask.cancel(false);
mTask = null;
mRunning = false;
isPause = false;
}
}
public void pause()
{
if(mRunning == true)
{
isPause = true;
}
}
public void resume()
{
isPause = false;
}
public boolean isRunning()
{
return mRunning;
}
private class TestTask extends AsyncTask<Void, Integer, Void>
{
@Override
protected void onPreExecute()
{
// TODO Auto-generated method stub
mCallback.onPreExecute();
mRunning = true;
}
@Override
protected Void doInBackground(Void... params)
{
// TODO Auto-generated method stub
for(int i = 0; !isCancelled() && i < 100; i++)
{
if(isPause == true)
{
sleep();
}
SystemClock.sleep(100);
publishProgress(i);
}
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
mCallback.onProgressUpdate(values[0]);
}
@Override
protected void onCancelled() {
// TODO Auto-generated method stub
mCallback.onCancelled();
mRunning = false;
}
@Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
mCallback.onPostExecute();
mRunning = false;
}
private void sleep()
{
try
{
while(isPause)
{
Thread.sleep(500);
}
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
}
setRetainInstance(true)