3

내 생각은 AsyncTask 안에 새 조각을 만든 다음 onPostExecute에 표시되는 진행률 표시 줄 조각으로 바꿉니다. 내 문제는 프래그먼트가 절대로 바뀌지 않으므로 진행 막대 조각으로 유지된다는 것입니다. 이 일을 할 수 없습니까? 나쁜 접근입니까? DetailFragment 내부에 진행률 막대를 표시해야합니까? (진행 막대가있는 파편이 많을 것입니다.)배경 스레드 내 조각을 바꿀 수 있습니까

@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(); 
    } 

} 

답변

2

이것이 작동하지 않아야하는 이론적 인 이유는 없습니다. 그러나 그것은 나에게 매우 이상한 접근법이라고 말했다.

일반적으로 AsyncTask.doInBackground()은 데이터 생성/다운로드/처리에 사용되며 AyncTask.onPostExecute()은 UI를 업데이트합니다. 하지만 두 가지 방법으로 UI 파트를 배포하고 있습니다.

또한 Fragment는 UI 클래스이며 데이터 크런치를 수행하는 데이 클래스를 사용하여 각 클래스의 용도를 다시 혼합합니다. 일반적으로, 내 프로젝트에서 나는 비슷한 것을 따르는 경향이있다. (일부 일반적인 이름을 보여주는 예제와 마찬가지로, 실제 물건에서는 의미있는 이름을 사용하고 일부 생성자는 무시할 수도있다.)

당신의 조각에
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); 
    // --- 

} 

+0

왜 데이터 parcelable을하는 것이 중요합니다 도움이되기를 바랍니다? (다시 작성한 후 특정 클래스를 전달해야한다는 것을 알았습니다.) 왜 setData() 메소드를 작성하지 않고 변수를 설정해야합니까? MyData _data; .. 공공 무효의 setData (MyData 데이터) {_ 데이터 = 데이터; } – Patrick

+1

나는 대답했다. 이것은 프래그먼트 수명주기 때문입니다. 프래그먼트 객체가 파괴되었지만 나중에 시스템에서 동일한 프래그먼트 (다시 버튼, 회전, 이미 관리자의 레이아웃 조각에 추가 등)가 필요한 경우 시스템은 동일한 번들을 프래그먼트로 전달하여 재 구축 할 수 있습니다 . 이와 같은 함수를 작성하는 경우에는 이런 일이 발생하지 않으며 조각에는 해당 조건에 대해 null 데이터가 있습니다. – Budius

관련 문제