how to return result from asyn call

2019-01-29 09:50发布

i have all my async calls in their own classes and so i dont want to have global vars being set aync'ly. To do this i want to return objects eg a string from my asunc postProcess methods.

can this be done?

Below is my general structure to my classes, i want to return a String for example from onPostExecute(). I see delegates are mentioned in other places but this seems very messy, sure there is a way to have a return type to the class or methods?

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条回答
The star\"
2楼-- · 2019-01-29 10:27

Some thing like below

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

And the listener class

public interface AsyncListener {
    void onTaskStarted();

    void onTaskFinished(String data);
}

and you can call like this

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

            @Override
            public void onTaskFinished(String data) {
//Do your stuff;
            }
        }).execute(parameter);
查看更多
欢心
3楼-- · 2019-01-29 10:31

Another option is to use AsyncTaskLoader. You derive your class not from AsyncTask, but from AsyncTaskLoader. In your Activity you need to implement LoaderCallbacks interface. The args you want to use in Loader, you put in Bundle. All information you want to get from Loader will be passed in method onLoadFinished(). Here's an example

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

}
查看更多
登录 后发表回答