在 onCreate() 中执行 HTTP GET 的最佳方式
Best way to execute HTTP GET in onCreate()
我正在编写连接到 REST API 的 Android 客户端。由于 Android 3.0 不允许在主线程上执行阻塞网络操作,所以我正在寻找实现它的最佳方法。
我已经使用 AsyncTask
管理了我的 objective,但它似乎是一个相当肮脏的实现,所以我想寻求建议。
从异步任务返回的数据用于更新 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 class 似乎很尴尬?
静态{
StrictMode.ThreadPolicy 政策 = 新 StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(政策);
}
使用此代码,您可以在主线程上使用网络操作。
使用 AsyncTask
实际上是一件好事,因为它的执行与 main activity 不同步,所以当你想做一些后台工作并需要 main UI 同时激活总是使用 AsyncTask
.
在主线程上进行网络操作的缺点是,它会使 UI 暂时没有响应,这看起来太迟钝,不是一个好习惯。
您可以开始的第一件事是使您的内部 AsyncTask
class 实现 static
,否则它将包含对主机 class 的隐式引用( Activity
),这意味着它不会被垃圾收集,直到任务还活着(让我们想象执行 NonBloquingGET
需要很多时间(你正坐在荒岛上的某个地方以拨号速度上网)并且您旋转屏幕,活动将保存在内存中)。第二步你能想到的就是为event bus实现一对IntentService and BroadcastReceiver. After you understand the key concepts behind it, you can take a look on 3rd party libraries, for example Retrofit for network communications, RxJava for events and Otto
我正在编写连接到 REST API 的 Android 客户端。由于 Android 3.0 不允许在主线程上执行阻塞网络操作,所以我正在寻找实现它的最佳方法。
我已经使用 AsyncTask
管理了我的 objective,但它似乎是一个相当肮脏的实现,所以我想寻求建议。
从异步任务返回的数据用于更新 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 class 似乎很尴尬?
静态{ StrictMode.ThreadPolicy 政策 = 新 StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(政策); }
使用此代码,您可以在主线程上使用网络操作。
使用 AsyncTask
实际上是一件好事,因为它的执行与 main activity 不同步,所以当你想做一些后台工作并需要 main UI 同时激活总是使用 AsyncTask
.
在主线程上进行网络操作的缺点是,它会使 UI 暂时没有响应,这看起来太迟钝,不是一个好习惯。
您可以开始的第一件事是使您的内部 AsyncTask
class 实现 static
,否则它将包含对主机 class 的隐式引用( Activity
),这意味着它不会被垃圾收集,直到任务还活着(让我们想象执行 NonBloquingGET
需要很多时间(你正坐在荒岛上的某个地方以拨号速度上网)并且您旋转屏幕,活动将保存在内存中)。第二步你能想到的就是为event bus实现一对IntentService and BroadcastReceiver. After you understand the key concepts behind it, you can take a look on 3rd party libraries, for example Retrofit for network communications, RxJava for events and Otto