2015-11-25 51 views
0

我在自己的類中擁有所有的異步調用,所以我不想讓全局變量設置爲異步。爲此,我想從asunc postProcess方法返回對象,例如一個字符串。如何從asyn調用返回結果

可以這樣做嗎?

下面是我的類的一般結構,我想從onPostExecute()返回一個字符串。我看到代表在其他地方被提到,但這看起來很混亂,肯定有辦法讓類或方法返回類型?

class GetStuffAsyncly extends AsyncTask<String, String, String> 
{ 
    // my vars.... 

    public myconstructor(String dialogMessage, Context con) 
    { 
     this.qDialog = new ProgressDialog(con); 
     this.dialogString = dialogMessage; 
     this.context = con; 
    } 

    /** 
    * Before starting background thread Show Progress Dialog 
    * */ 
    @Override 
    protected void onPreExecute() 
    { 
     super.onPreExecute(); 
     do stuff like fire dialog 
    } 

    @Override 
    protected String doInBackground(String... args) 
    { 
     // do stuff in background... 

     return data; 
    } 

    /** 
    * After completing background task Dismiss the progress dialog 
    * **/ 
    protected void onPostExecute(String jsonString) 
    { 
     // dismiss the dialog after getting all data 
     dialog.dismiss(); 
    } 
} 
+2

使用回調(接口)是正確的方式 – Emil

+0

Thx爲響應老闆。如果可能,你可以擴展我的代碼來演示回調嗎? – Fearghal

+0

檢查這個問題的答案:http://stackoverflow.com/questions/6053602/what-arguments-are-passed-into-asynctaskarg1-arg2-arg3 – karvoynistas

回答

4

有些東西像下面

class GetStuffAsyncly extends AsyncTask<String, String, String> { 
    String dialogString; 
    ProgressDialog dialog; 
    Context context; 
    AsyncListener listener; 
    // my vars.... 

    public GetStuffAsyncly(String dialogMessage, Context con, AsyncListener listener) { 
     this.dialog = new ProgressDialog(con); 
     this.dialogString = dialogMessage; 
     this.context = con; 
     this.listener = listener; 
    } 

    /** 
    * Before starting background thread Show Progress Dialog 
    */ 
    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     listener.onTaskStarted(); 
    } 

    @Override 
    protected String doInBackground(String... args) { 
     // do stuff in background... 

     return data; 
    } 

    /** 
    * After completing background task Dismiss the progress dialog 
    **/ 
    protected void onPostExecute(String jsonString) { 
     // dismiss the dialog after getting all data 
     dialog.dismiss(); 
     listener.onTaskFinished(jsonString); 
    } 
} 

與聽者類

public interface AsyncListener { 
    void onTaskStarted(); 

    void onTaskFinished(String data); 
} 

,你可以這樣調用

new GetStuffAsyncly(message, this, new AsyncListener() { 
      @Override 
      public void onTaskStarted() { 
       //do your stuff 
      } 

      @Override 
      public void onTaskFinished(String data) { 
//Do your stuff; 
      } 
     }).execute(parameter); 
+0

偉大的thx。一個問題,我如何使用Listener類AsyncListener,我想我稱之爲無論我想返回我的數據,但我怎麼稱它呢? – Fearghal

+0

好吧,我會給這個去。我在哪裏指定哪些var從postExecute返回?它是listener.onTaskFinished(jsonString);? – Fearghal

+0

我從哪裏檢索數據?你說的//做你的東西?什麼var包含postexecute的數據?我的目標是將來自異步的結果數據導入到我的活動中 - 它從哪裏進入活動? – Fearghal

0

另一種選擇是使用AsyncTaskLoader。你不是從AsyncTask中派生出你的班級,而是從AsyncTaskLoader派生出你的班級。在您的活動中,您需要實施LoaderCallbacks界面。你想在Loader中使用的參數,你放在Bundle中。您想從Loader獲得的所有信息都將通過方法onLoadFinished()傳遞。下面是一個例子

public class BaseInitLoader extends AsyncTaskLoader<Employee[]> { 
     Context mContext; 
     boolean firstrun; 

     public BaseInitLoader(Context context, Bundle args) { 
      super(context); 
      mContext = context; 
      firstrun = args.getBoolean("firstrun"); 

     } 

     @Override 
     protected void onStartLoading() { 
      super.onStartLoading(); 
      forceLoad(); 
     } 

     @Override 
     public Employee[] loadInBackground() { 
      MainActivity activity =(MainActivity) mContext; 



      Cursor cursor = new DatabaseFiller(activity.getDb(), mContext, firstrun).fillTable(); 
      ArrayList<Employee> list = new ArrayList<>(); 
      QueryResultIterable<Employee> itr = null; 

      try { 

       itr = cupboard().withCursor(cursor).iterate(Employee.class); 
       for(Employee employee: itr){ 
        list.add(employee); 
       } 


      } finally { 
       // close the cursor 
       if (itr != null) { 
        itr.close(); 
       } 
      } 
      Employee[] employees = new Employee[list.size()]; 
      employees = list.toArray(employees); 
      return employees; 
     } 
    } 
public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks, View.OnClickListener { 

    /** 
    * ATTENTION: This was auto-generated to implement the App Indexing API. 
    * See https://g.co/AppIndexing/AndroidStudio for more information. 
    */ 
    TextView priority, name, innerPhone, mobilePhone, position; 
    Button cityBtn; 
    CharSequence[] cities; 
    SQLiteDatabase db; 
    Context mContext; 
    private Cursor cursor; 
    private SQLiteDatabase database; 
    private ListView listView; 
    private TextView nameTxt; 
    private EmployeeAdapter adapter; 
    public static final String LOG_TAG = "Database"; 
    SharedPreferences prefs; 
    private boolean firstrun; 
    private ViewPager viewPager; 
    private TabLayout tabLayout; 


    private final int INITIAL = 1; 
    private final int SORT_NAME = 2; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     mContext = this; 
     Bundle args = new Bundle(); 

     prefs = getSharedPreferences("ua.lanet.PipBoy", MODE_PRIVATE); 
     if(prefs.getBoolean("firstrun", true)){ 
      args.putBoolean("firstrun", true); 
      prefs.edit().putBoolean("firstrun", false).apply(); 

     } 
     else{ 
      args.putBoolean("firstrun", false); 
     } 


     getLoaderManager().initLoader(INITIAL, args, this); 


     PipBoyDataHelper helper = new PipBoyDataHelper(this); 
     db = helper.getWritableDatabase(); 
} 


    public SQLiteDatabase getDb() { 
     return db; 
    } 

    @Override 
    public Loader onCreateLoader(int id, Bundle args) { 

    return new BaseInitLoader(mContext, args); 
    } 

    @Override 
    public void onLoadFinished(Loader loader, Object data) { 

     //do something with the data. Cast Object to your return type of loader 

    } 

    @Override 
    public void onLoaderReset(Loader loader) { 
} 

    @Override 
    public void onClick(View v) { 
     switch (v.getId()){ 
      case R.id.text: 
       getLoaderManager().initLoader(SORT_NAME, null, this); 
       break; 
     } 
    } 



    private class ViewPagerAdapter extends FragmentPagerAdapter{ 
     private final List<Fragment> mFragmentList = new ArrayList<>(); 
     private final List<String> mFragmentTitleList = new ArrayList<>(); 

     public ViewPagerAdapter(FragmentManager fm) { 
      super(fm); 
     } 

     @Override 
     public Fragment getItem(int position) { 
      return mFragmentList.get(position); 
     } 

     @Override 
     public int getCount() { 
      return mFragmentList.size(); 
     } 
     @Override 
     public CharSequence getPageTitle(int position) { 
      return mFragmentTitleList.get(position); 
     } 
     public void addFragment(Fragment fragment, String title) { 
      mFragmentList.add(fragment); 
      mFragmentTitleList.add(title); 
     } 
    } 

}