2013-03-07 45 views
8

Tôi đang cố gắng triển khai gọi lại giữa AsyncTask và Fragment nhưng không thể tìm thấy thông tin chính xác cách thực hiện. Vấn đề là tất cả các triển khai gọi lại là giữa hoạt động và asynctask nhưng tôi cần giữa phân đoạn và asynctask. Ai đó có thể cho tôi ví dụ làm việc nhỏ như thế nào để thực hiện nó mà không có hoạt động. Cấu trúc hành động của tôi: Hộp thoại cuộc gọi Fragment -> chọn một cái gì đó và gửi yêu cầu máy chủ đến nhiệm vụ không đồng bộ -> nhiệm vụ không đồng bộ xử lý mọi thứ và cập nhật chế độ xem và một số biến. Vấn đề chính của tôi là tôi gọi prepareData() chỉ một lần trong onCreate và khi tôi đi bộ giữa các mảnh khác và trả về trở lại tôi thấy dữ liệu cũ. Đó là để nói rằng không có đủ để cập nhật chỉ xem trong onPost của asynctask. Nó sẽ là tốt để có callback mà sẽ cập nhật toàn bộ các biến.Android: Gọi lại AsyncTask thành Phân đoạn (Không hoạt động)

public class TermsAndConditionsFragment extends SherlockFragment implements OnClickListener, OnTouchListener, OnItemClickListener, onTaskListener { 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    fm = getSherlockActivity().getSupportFragmentManager(); 


    prepareData(); 
} 

public void prepareData() { 
    termsAndConditionsM = new TermsAndConditionsManager(getSherlockActivity()); 
    termsAndConditions = termsAndConditionsM.getTermsAndConditions(); 

    if (termsAndConditions != null) { 
       int totalPayments = Integer.valueOf(termsAndConditions.get(ServerAPI.NO_OF_PAYMENTS)); 
     if (totalPayments > 0) { 
      paymentsData = termsAndConditionsM.getpayments(); 

      if (paymentsData != null) { 

       payments = new ArrayList<Payment>(); 

       for (int i = 1; i <= totalPayments; i++) { 
        paymentValues = new Payment(); 
        paymentValues.setPaymentID(Integer.valueOf(paymentsData.get(ServerAPI.PAYMENT_NO + "_" + i))); 
        paymentValues.setPaymentDate(paymentsData.get(ServerAPI.PAYMENT_DATE + "_" + i)); 
        paymentValues.setPaymentTotalAmount(paymentsData.get(ServerAPI.PAYMENT_TOTAL + "_" + i)); 
        payments.add(paymentValues); 
       } 
      } 
     } 
    } 
} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 

    rootView = init(inflater, container); 

    if (payments != null || termsAndConditions != null) 
     updateTermsAndConditionsView(); 

    return rootView; 
} 

private View init(LayoutInflater inflater, ViewGroup container) { 
    rootView = inflater.inflate(R.layout.fragment_terms_and_conditions, container, false); 

    ... 
    return rootView; 
} 

public void updateTermsAndConditionsView() { 
    etHowMuch.setText("£" + termsAndConditions.get(ServerAPI.AMOUNT_OF_CREDIT)); 
    etForHowLong.setText(Helpers.ConvertDays2Date(Integer.valueOf(termsAndConditions.get(ServerAPI.TERM_OF_AGREEMENT_IN_DAYS)))); 

    PaymentAdapter adapter = new PaymentAdapter(getSherlockActivity(), R.layout.custom_loan_item, payments); 
    lvPayments.setAdapter(adapter); 

    tvNoOfPayments.setText(termsAndConditions.get(ServerAPI.NO_OF_PAYMENTS)); 
    tvFirstPayment.setText(termsAndConditions.get(ServerAPI.FIRST_PAYMENT_DATE)); 
    tvTotalRepayable.setText("£" + termsAndConditions.get(ServerAPI.TOTAL_REPAYABLE)); 
} 

@Override 
public void onClick(View v) { 
    ft = fm.beginTransaction(); 

    howMuch = etHowMuch.getText().toString(); 
    forHowLong = etForHowLong.getText().toString(); 

    switch (v.getId()) { 
     case R.id.etHowMuch: 
      f = new NumberPaymentsPickerFragment(); 
      args = new Bundle(); 
      args.putInt(Const.HOW_MUCH, Integer.valueOf(howMuch.replace("£", ""))); 
      args.putDouble(ServerAPI.PAYMENT_STEP, Const.PAYMENT_STEP); 
      args.putString(Const.STATE, ServerAPI.TERMS_AND_CONDITIONS); 
      f.setArguments(args); 
      f.setTargetFragment(this, DIALOG_FRAGMENT); 
      f.show(getActivity().getSupportFragmentManager(), Const.HOW_MUCH); 
      break; 
     case R.id.etForHowLong: 
      f = new NumberPaymentsPickerFragment(); 
      args = new Bundle(); 
      args.putInt(Const.FOR_HOW_LONG, Integer.valueOf(Helpers.ConvertDate2Days(forHowLong))); 
      args.putDouble(ServerAPI.PAYMENT_STEP, Const.PAYMENT_STEP); 
      args.putString(Const.STATE, ServerAPI.TERMS_AND_CONDITIONS); 
      f.setArguments(args); 
      f.setTargetFragment(this, DIALOG_FRAGMENT); 
      f.show(getActivity().getSupportFragmentManager(), Const.FOR_HOW_LONG); 
      break; 
     case R.id.tvPersonalDetails: 
      sfm.saveCurFragment(ServerAPI.PERSONAL_DETAILS, 0); 
      ft.replace(android.R.id.content, new PersonalDetailsFragment(), ServerAPI.PERSONAL_DETAILS).addToBackStack(null).commit(); 
      break; 
     case R.id.tvAgreementDetails: 
      sfm.saveCurFragment(ServerAPI.AGREEMENT_DETAILS, 0); 
      ft.replace(android.R.id.content, new AgreementDetailsFragment(), ServerAPI.AGREEMENT_DETAILS).addToBackStack(null).commit(); 
      break; 
     case R.id.bApply: 

      break; 
    } 

@Override 
public void onUpdateData() { 
    Log.d(TAG, "Update data"); 

} 

} 

DialogFragment:

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    Bundle args = getArguments(); 

    ... 
} 

public Dialog onCreateDialog(Bundle savedInstanceState) { 

    ... 

     return createDialog(v, R.string.for_how_long, etHowMuch, etForHowLong, etPromotionCode); 
    } 
    return null; 
} 
private Dialog createDialog(View view, int titleResID, final EditText howMuchField, final EditText forHowLongField, final EditText promotionCodeField) { 
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); 
    builder.setTitle(titleResID); 
    builder.setView(view); 
    builder.setPositiveButton(R.string.set, new DialogInterface.OnClickListener() { 
     @Override 
     public void onClick(DialogInterface dialog, int id) { 

      doShowProgress(); 

     } 

     private void doShowProgress() { 


      ExecuteServerTaskBackground task = new 
        ExecuteServerTaskBackground(getActivity()); 
       task.action = ServerAPI.GET_TERMS_AND_CONDITIONS; 
       onTaskListener listener = new onTaskListener() { 

       @Override 
       public void onUpdateData() { 
        Log.d(TAG, "Updaaate"); 

       } 
      }; 
      task.setListener(listener); 
      task.args = args; 
      task.execute(); 
     } 

    }).setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { 
     @Override 
     public void onClick(DialogInterface dialog, int id) { 
      dialog.cancel(); 
     } 
    }); 
    return builder.create(); 
} 

AsyncTask:

onTaskListener mListener; 

public interface onTaskListener { 
    void onUpdateData(); 
} 

public void setListener(onTaskListener listener){ 
    mListener = listener; 
} 
public ExecuteServerTaskBackground(Activity activity) { 
    this.mActivity = activity; 
    this.mContext = activity.getApplicationContext(); 
} 

@Override 
protected void onPreExecute() { 
    pb = (ProgressBar) mActivity.findViewById(R.id.progressBar1); 
    pb.setVisibility(View.VISIBLE); 
} 

@Override 
protected Void doInBackground(Void... params) { 
    ServerAPI server = new ServerAPI(mContext); 
    if (!args.isEmpty()) 
     server.serverRequest(action, args); 
    else 
     server.serverRequest(action, null); 
    return null; 
} 

@Override 
protected void onPostExecute(Void result) { 
mListener.onUpdateData(); 

//There is I just update view but how to update whole variables throughtout callback?   
//    tvNoOfPayments = (TextView) mActivity.findViewById(R.id.tvNoOfPaymentsValue); 
//    tvFirstPayment = (TextView) mActivity.findViewById(R.id.tvFirstPaymentValue); 
//    tvTotalRepayable = (TextView) mActivity.findViewById(R.id.tvTotalRepayableValue); 
// 
//    lvPayments = (ListView) mActivity.findViewById(R.id.lvData); 
// 
//    termsConditionsM = new TermsAndConditionsManager(mContext); 
// 
//    termsAndConditions = termsConditionsM.getTermsAndConditions(); 
// 
//    int totalPayments = Integer.valueOf(termsAndConditions.get(ServerAPI.NO_OF_PAYMENTS)); 
// 
//    if (totalPayments > 0) { 
//     if (termsAndConditions != null) { 
//      tvNoOfPayments.setText(termsAndConditions.get(ServerAPI.NO_OF_PAYMENTS)); 
//      tvFirstPayment.setText(termsAndConditions.get(ServerAPI.FIRST_PAYMENT_DATE)); 
//      tvTotalRepayable.setText("£" + termsAndConditions.get(ServerAPI.TOTAL_REPAYABLE)); 
//     } 
// 
//     paymentsData = termsConditionsM.getpayments(); 
// 
//     if (paymentsData != null) { 
//      Log.d(TAG, paymentsData.toString()); 
// 
//      payments = new ArrayList<Payment>(); 
// 
//      for (int i = 1; i <= totalPayments; i++) { 
//       paymentValues = new Payment(); 
//       paymentValues.setPaymentID(Integer.valueOf(paymentsData.get(ServerAPI.PAYMENT_NO + "_" + i))); 
//       paymentValues.setPaymentDate(paymentsData.get(ServerAPI.PAYMENT_DATE + "_" + i)); 
//       paymentValues.setPaymentTotalAmount(paymentsData.get(ServerAPI.PAYMENT_TOTAL + "_" + i)); 
//       payments.add(paymentValues); 
//      } 
// 
//      PaymentAdapter adapter = new PaymentAdapter(mContext, R.layout.custom_loan_item, payments); 
//      lvPayments.setAdapter(adapter); 
//     } 
    //    

    } 

    pb.setVisibility(View.GONE); 
    super.onPostExecute(result); 
} 

Trả lời

25

Nếu không có lấy mã của bạn trong việc xem xét, tôi sẽ đăng quan trọng nhất để thực hiện một cuộc gọi lại chức năng.


TestFragment:

public class TestFragment extends Fragment { 

    /* Skipping most code and I will only show you the most essential. */  
    private void methodThatStartsTheAsyncTask() { 
     TestAsyncTask testAsyncTask = new TestAsyncTask(new FragmentCallback() { 

      @Override 
      public void onTaskDone() { 
       methodThatDoesSomethingWhenTaskIsDone(); 
      } 
     }); 

     testAsyncTask.execute(); 
    } 

    private void methodThatDoesSomethingWhenTaskIsDone() { 
     /* Magic! */ 
    } 

    public interface FragmentCallback { 
     public void onTaskDone(); 
    } 
} 

TestAsyncTask:

public class TestAsyncTask extends AsyncTask<Void, Void, Void> { 
    private FragmentCallback mFragmentCallback; 

    public TestAsyncTask(FragmentCallback fragmentCallback) { 
     mFragmentCallback = fragmentCallback; 
    } 

    @Override 
    protected Void doInBackground(Void... params) { 
     /* Do your thing. */ 
     return null; 
    } 

    @Override 
    protected void onPostExecute(Void result) { 
     mFragmentCallback.onTaskDone(); 
    } 
} 
+0

Đó là những gì tôi có bây giờ. Và phần này đang làm việc nhưng tôi muốn bắt tin nhắn không ở cùng một nơi được gọi là AsyncTask. Cấu trúc của tôi là MainFragment (ở đây tôi muốn bắt tin nhắn) -> DialogFragment (gọi asynctask) -> async task (xử lý và trả về kết quả trong đoạn min). Bây giờ, gọi lại đang hoạt động bình thường chỉ để kết nối giữa DialogFragment và AsyncTask, nhưng làm thế nào để gửi kết quả trực tiếp đến mainFragment? – user1376885

+0

Hoặc nếu chỉ có thể thực hiện trong suốt hai cuộc gọi lại (1 cuộc gọi lại - AsyncTask -> DialogFragment, 2 gọi lại - DialogFragment-> MainFragment) thì cách gửi trình nghe đến DialogFragment. Không thể sử dụng setLIstener như trong AsyncTask. – user1376885

+0

@ user1376885 Bạn có lưu kết quả vào cơ sở dữ liệu hoặc tải một thứ không thể lưu? Thực hành tốt là giữ cách tiếp cận "không quốc tịch" có nghĩa là bạn sẽ không gửi trực tiếp nội dung giữa các Phân đoạn hoặc Hoạt động. Bạn sẽ muốn lưu nó vào một cơ sở dữ liệu và khi Fragment/Activity bắt đầu bạn đọc cơ sở dữ liệu và tải các giá trị và trình bày nó. Vậy, bạn đang làm gì trong AsyncTask của mình? Có vẻ như bạn có thể lưu nó vào cơ sở dữ liệu. –

Các vấn đề liên quan