Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/393.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 是否可以在后台线程内交换片段_Java_Android_Asynchronous_Android Asynctask_Android Fragments - Fatal编程技术网

Java 是否可以在后台线程内交换片段

Java 是否可以在后台线程内交换片段,java,android,asynchronous,android-asynctask,android-fragments,Java,Android,Asynchronous,Android Asynctask,Android Fragments,我的想法是在AsyncTask中创建新的片段,然后在onPostExecute上,我将它与显示的进度条片段交换。我的问题是,片段从未交换,因此它与进度条片段保持一致。这不可能吗?这是一个糟糕的方法吗?我应该把进度条放在DetailFragment中吗?(将有很多带有进度条的片段) @覆盖 受保护的void onStart(){ super.onStart(); getSupportFragmentManager().beginTransaction() .replace(R.id.content

我的想法是在AsyncTask中创建新的片段,然后在onPostExecute上,我将它与显示的进度条片段交换。我的问题是,片段从未交换,因此它与进度条片段保持一致。这不可能吗?这是一个糟糕的方法吗?我应该把进度条放在DetailFragment中吗?(将有很多带有进度条的片段)

@覆盖
受保护的void onStart(){
super.onStart();
getSupportFragmentManager().beginTransaction()
.replace(R.id.content_frame,new ProgressBarFragment()).commit();
TestSwapFragment d=新的TestSwapFragment();
d、 执行(数据);
}
类TestSwapFragment扩展了AsyncTask{
FragmentData数据=null;
@凌驾
受保护的MyFragment doInBackground(FragmentData…参数){
试一试{
Thread.sleep(15000);//模拟下面的长时间运行方法
}捕获(中断异常e){
e、 printStackTrace();
}
this.data=params[0];
DetailFragment df=新的DetailFragment();
df.ExecuteFragment(this.data);//长时间运行
返回df;
}
@凌驾
受保护的void onPostExecute(MyFragment结果){
super.onPostExecute(结果);
if(this.data.Position==FragmentPosition.PaneOne)
getSupportFragmentManager().beginTransaction()
.replace(R.id.content_frame,result).commit();
其他的
getSupportFragmentManager().beginTransaction()
.replace(R.id.content_frame2,result).commit();
}
}

我看不出任何理论上的理由说明这不可行。但是,尽管如此,这对我来说是一种非常奇怪的方式

AsyncTask.doInBackground()
通常用于创建/下载/处理数据,
AyncTask.onPostExecute()
用于更新UI。但您在这两种方法上都分发UI部件

此外,片段是一个UI类,您使用它进行数据处理,再次混合了每个类的用途。作为一般规则,在我的项目中,我倾向于遵循类似的规则(就像显示一些通用名称的示例一样,但在真实的项目中,使用有意义的名称,而且我可能会忽略一些构造函数,只是为了保持简短)


希望能有所帮助

为什么使数据可打包很重要?(重写之后,我意识到我需要传入一个特定的类)为什么不创建一个方法setData(),该方法集是一个变量?MyData\u data。。公共无效setData(MyData data){{u data=data;}我在回答时说。这是因为碎片的生命周期。如果正在销毁片段对象,但系统稍后需要相同的片段(后退按钮、旋转、添加到管理器上已有的布局片段等),系统将向片段传递相同的捆绑包,以便可以重新构建。如果您只是创建一个这样的函数,就不会发生这种情况,并且您的片段将在这些条件下具有空数据。
@Override
protected void onStart() {      
    super.onStart();
    getSupportFragmentManager().beginTransaction()
            .replace(R.id.content_frame, new ProgressBarFragment()).commit();
    TestSwapFragment d = new TestSwapFragment();
    d.execute(data);
}

class TestSwapFragment extends AsyncTask<FragmentData, Void, MyFragment> {

FragmentData data = null;

    @Override
    protected MyFragment doInBackground(FragmentData... params) {

        try {
            Thread.sleep(15000); // Simulate the long running method below
        } catch (InterruptedException e) {                  
            e.printStackTrace();
        }

        this.data = params[0];
        DetailFragment df= new DetailFragment();
        df.ExecuteFragment(this.data); // Long running

        return df;
    }

    @Override
    protected void onPostExecute(MyFragment result) {               
        super.onPostExecute(result);

        if (this.data.Position == FragmentPosition.PaneOne)
                getSupportFragmentManager().beginTransaction()
                .replace(R.id.content_frame, result).commit();
        else
                getSupportFragmentManager().beginTransaction()
                .replace(R.id.content_frame2, result).commit();
    }

}
MyActivity.java
public class MyActivity extends Activity{


      private class MyWorker extends AsyncTask<SomeDataObject, Integer, SomeDataListObject>{
            @Override
            protected MyFragment doInBackground(SomeDataObject... params) {
                 // in here we use SomeDataObject to generate the SomeDataListObject
                 return MyDataCruncher.processData(someDataObject);
                 // see it's a static method, process A and generates B, that's all.
                 // but very important that it's its own class, separate from Activity and Fragment
            }

            @Override
            protected void onPostExecute(SomeDataListObject result){
                if(results != null){
                     // Here we create the fragment, pass the data to it and do the transaction
                     getSupportFragmentManager().beginTransaction().replace(R.id.content_frame, MyFrag.newInstance(result)).commit();

                }else{ /* do some error handling or whatever */ }
            }
}
public class MyFrag extends Fragment{
    private static String KEY_DATA = "_key_data_"
    public static MyFrag newInstance(SomeDataListObject data){
        MyFrag frag = new MyFrag();
        Bundle b = new Bundle();
        frag.setArguments(b);
        // it's important to make your data parcelable and pass it with a Bundle as part of the fragment life-cycle
        b.putParcelableArrayList(KEY_DATA, data);
        return frag;
    }

    // then inside onCreateView
     SomeDataListObject data = getArguments.getParcelableArray(KEY_DATA);
    // ---

}