我正在编写连接到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类似乎很尴尬?
答案 0 :(得分:2)
你可以开始的第一件事就是使你的内部AsyncTask
类实现static
,否则它将保存对宿主类(Activity
)的隐式引用,这意味着它在任务生效之前不会被垃圾收集(让我们想象NonBloquingGET
的执行需要花费很多时间(你在荒岛上的某个地方以拨号速度坐着)并且你旋转屏幕,活动将保持不变在记忆中)。您可以想到的第二步是实现一对IntentService和BroadcastReceiver。在了解了其背后的关键概念之后,您可以查看第三方库,例如Retrofit用于网络通信,RxJava用于事件,Otto用于事件总线。
答案 1 :(得分:0)
使用AsyncTask
实际上是一件好事,因为它的执行与主活动不同步,所以当你想做一些后台工作并且需要主UI同时处于活动状态时总是使用AsyncTask
。
在主线程上进行网络操作的缺点是它会暂时使UI无响应,这看起来太迟钝而且不是一个好习惯。
答案 2 :(得分:-2)
static { StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()。permitAll()。build(); StrictMode.setThreadPolicy(政策); }
使用此代码,您可以在主线程上使用网络操作。