2013-03-07 11 views
8

मैं AsyncTask और Fragment के बीच कॉलबैक लागू करने का प्रयास कर रहा हूं लेकिन इसे सही जानकारी नहीं मिल सकती है। मुद्दा यह है कि सभी कॉलबैक कार्यान्वयन गतिविधि और asynctask के बीच हैं, लेकिन मुझे खंड और asynctask के बीच की जरूरत है। क्या कोई मुझे गतिविधि के बिना इसे कार्यान्वित करने के लिए छोटे कामकाजी उदाहरण दे सकता है। मेरी क्रिया संरचना: फ्रैगमेंट कॉल डायलॉग फ्रैगमेंट -> कुछ चुनें और एसिंक कार्य को सर्वर अनुरोध भेजें -> async कार्य प्रक्रिया सब कुछ और अद्यतन दृश्य और कुछ चर। मेरी मुख्य समस्या यह है कि मैं केवल तैयार करने के लिए readyData() को कॉल करता हूं और जब मैं अन्य टुकड़े के बीच चलता हूं और रिटर्न वापस आ जाता है तो मुझे पुराना डेटा दिखाई देता है। यही कहना है कि एसिंक्टस्क के पोस्ट पर केवल अपडेट को अपडेट करने के लिए पर्याप्त नहीं है। कॉलबैक होना अच्छा होगा जो पूरे चर को अपडेट करेगा।एंड्रॉइड: कॉलबैक AsyncTask फ्रेगमेंट (गतिविधि नहीं)

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

उत्तर

25

विचार में अपने कोड लेने के बिना मैं एक कार्यात्मक कॉलबैक बनाने के लिए सबसे जरूरी पोस्ट करेंगे।


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

है यही कारण है कि मैं अब है। और यह हिस्सा काम कर रहा है, लेकिन मैं उसी स्थान पर संदेश नहीं पकड़ना चाहता जहां एसिंक टास्क कहा जाता था। मेरी संरचना मेनफ्रैगमेंट है (यहां मैं संदेश पकड़ना चाहता हूं) -> डायलॉग फ्रैगमेंट (कॉल एसिंक्टास्क) -> एसिंक कार्य (प्रसंस्करण और रिटर्न परिणाम न्यूनतम खंड में)। अब, कॉलबैक सामान्य रूप से केवल डायलॉगफ्रैगमेंट और असिनकटास्क के बीच कनेक्शन के लिए काम कर रहा है, लेकिन परिणाम सीधे मुख्यफ्रैगमेंट को कैसे भेज सकता है? – user1376885

+0

या तो यदि केवल दो कॉलबैक (1 कॉलबैक - असिनकटास्क -> डायलॉग फ्रैगमेंट, 2 कॉलबैक - डायलॉग फ्रैगमेंट-> मेनफ्रैगमेंट) में करना संभव है तो डायलॉगफ्रैगमेंट में श्रोता को कैसे भेजें। SetLIstener का उपयोग करना संभव नहीं है क्योंकि यह AsyncTask में था। – user1376885

+0

@ user1376885 क्या आप परिणाम को डेटाबेस में सहेजते हैं या आप ऐसा कुछ लोड करते हैं जिसे सहेजा नहीं जा सकता है? अच्छा अभ्यास एक "स्टेटलेस" दृष्टिकोण रखना है जिसका अर्थ है कि आप सीधे टुकड़ों या गतिविधियों के बीच सामान नहीं भेजेंगे। आप इसे डेटाबेस में सहेजना चाहते हैं और जब फ्रैगमेंट/गतिविधि शुरू होती है तो आप डेटाबेस को पढ़ते हैं और मान लोड करते हैं और इसे प्रस्तुत करते हैं। तो, आप अपने AsyncTask में क्या कर रहे हैं? ऐसा लगता है कि आप इसे डेटाबेस में सहेज सकते हैं। –

संबंधित मुद्दे