在onCreate()中执行HTTP GET的最佳方法

时间:2015-03-29 19:41:09

标签: java android rest android-asynctask retrofit

我正在编写连接到REST API的Android客户端。由于Android 3.0不允许在主线程上执行阻塞网络操作,因此我正在寻找实现此功能的最佳方法。 我使用AsyncTask管理了我的目标,但这似乎是一个相当肮脏的实现,所以我想征求意见。 从异步任务返回的数据用于更新UI。

MainActivity.java

   
public class MainActivity extends ActionBarActivity{

    ListView establishment_list;
    CustomListAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        establishment_list = (ListView) findViewById(R.id.establishment_list);
        adapter = new CustomListAdapter( this, R.layout.establishment_row_layout, new String[]{"Loading data..."} );
        establishment_list.setAdapter(adapter);

        View header = (View) getLayoutInflater().inflate(R.layout.establishment_headerview, null);
        establishment_list.addHeaderView(header);
        // GET establishments from REST API
        new NonBloquingGET().execute();
    }

    /* DIRTY IMPLEMENTATION */
    private class NonBloquingGET extends AsyncTask<List<Establishment>, Void, List<Establishment>> {

        List<Establishment> establishments;

        @Override
        protected List<Establishment> doInBackground(List<Establishment>... params) {
            /* This is a synchronous call using the Retrofit library*/
            establishments = Client.getInstance().getEstablishments();

            return establishments;
        }

        @Override
        protected void onPostExecute(List<Establishment> result) {
            Log.d("ASYNC TASK", result.toString());
            List<String> data = new ArrayList<>();
            for (Establishment e : result){
                data.add(e.getName());
            }
            adapter.updateDataSet( data.toArray(new String[data.size()]) );
        }

        @Override
        protected void onPreExecute() {
        }

        @Override
        protected void onProgressUpdate(Void... values) {
        }
    }
}

有没有更好的方法来实现它,因为我计划添加更多活动并为每个活动添加AsyncTask类似乎很尴尬?

3 个答案:

答案 0 :(得分:2)

你可以开始的第一件事就是使你的内部AsyncTask类实现static,否则它将保存对宿主类(Activity)的隐式引用,这意味着它在任务生效之前不会被垃圾收集(让我们想象NonBloquingGET的执行需要花费很多时间(你在荒岛上的某个地方以拨号速度坐着)并且你旋转屏幕,活动将保持不变在记忆中)。您可以想到的第二步是实现一对IntentServiceBroadcastReceiver。在了解了其背后的关键概念之后,您可以查看第三方库,例如Retrofit用于网络通信,RxJava用于事件,Otto用于事件总线。

答案 1 :(得分:0)

使用AsyncTask实际上是一件好事,因为它的执行与主活动不同步,所以当你想做一些后台工作并且需要主UI同时处于活动状态时总是使用AsyncTask

在主线程上进行网络操作的缺点是它会暂时使UI无响应,这看起来太迟钝而且不是一个好习惯。

答案 2 :(得分:-2)

static {         StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()。permitAll()。build();         StrictMode.setThreadPolicy(政策);     }

使用此代码,您可以在主线程上使用网络操作。