我名为AllStores
的活动中的列表仅包含null。我需要这个列表,因为我想稍后填充我的ListView。问题是由于我的回调是最后执行而引起的。
为了澄清我在下面做了一个截图:
链接:http://i.imgur.com/bIkWjld.png
屏幕截图还说明了我真正想要的内容。为了达到这个目的,我尝试了AsyncTask
。然而,正如您在屏幕截图中看到的那样,它没有成功。
以下是代码:
EDIT 2.0我已将getSubprise()
方法更改为同步并使用AsyncTask
AllStores.java:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Response<List<Store>> subprises = new StoreService().getSubprises();
System.out.println("AllStores (Activity) - subprise " + subprises);
}
StoreService.java:
public Response<List<Store>> getSubprises() {
new LongOperation().execute("");
System.out.println("getStores (StoreService.java) value "+ getStores());
return getStores();
}
private class LongOperation extends AsyncTask<String, Void, Response<List<Store>>> {
@Override
protected Response<List<Store>> doInBackground(String... params) {
System.out.println("doInBackground executed second");
try {
Call<List<Store>> call = subpriseAPI.listStores();
stores=call.execute();
Iterator it=stores.body().iterator();
// while(it.hasNext())
// System.out.println(((Store)it.next()).getSTREET());
} catch (IOException e) {
e.printStackTrace();
}
return stores;
}
@Override
protected void onPreExecute() {
//Can't put the call here because this is the main thread
System.out.println("onPreExecute first");
}
@Override
protected void onPostExecute(Response<List<Store>> result) {
//Can't put the call here because this is the main thread
setStores(stores);
}
}
public Response<List<Store>> getStores() {
return stores;
}
public void setStores(Response<List<Store>> stores) {
this.stores = stores;
}
但是我现在仍然得到相同的结果,请参阅下面的屏幕截图:
link:http://i.imgur.com/GOGFXMR.png
屏幕截图与上面的屏幕截图相同。
答案 0 :(得分:1)
要将后台线程的结果传递给主线程,我必须使用AsyncTask.get()。通过使用它我可以在我的stores
变量中看到一个值而不是一个空值。
您可以在下面看到我想要查看的代码:
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public Response<List<Store>> getSubprises() throws IOException, ExecutionException, InterruptedException {
LongOperation longOperation = new LongOperation();
longOperation.execute("");
stores = longOperation.get();
return stores;
}
private class LongOperation extends AsyncTask<String, Void, Response<List<Store>>> {
@Override
protected Response<List<Store>> doInBackground(String... params) {
//System.out.println("doInBackground executed second");
try {
Call<List<Store>> call = subpriseAPI.listStores();
stores=call.execute();
} catch (IOException e) {
e.printStackTrace();
}
return stores;
}
@Override
protected void onPreExecute() {
//Can't put the call here because this is the main thread
//System.out.println("onPreExecute first");
}
@Override
protected void onPostExecute(Response<List<Store>> result) {
//Can't put the call here because this is the main thread
}
}
答案 1 :(得分:0)
我认为让Retrofit在其内部HTTP执行程序内部调用调用会更好。这将涉及将您的API接口更改为以下内容:
public interface SubpriseAPI {
@GET("api/locations/get")
List<Store> listStores();
}
...并包含Retrofit的任何相关配置,以便将反序列化处理为Store
类型。
但是,如果你想自己调用这些调用,你可以考虑托管你自己的执行器实例(或者你想运行你的工作线程),就像这样(不是这个确切的实现,但你应该明白) :
class StoreService {
...
private final ExecutorService executorService = Executors.newCachedThreadPool();
...
public Response<List<Store>> getSubprises() {
executorService.submit(new Callable<List<Store>>() {
@Override
public List<Store> call() throws Exception {
final Call<List<Store>> call = subpriseAPI.listStores();
try {
if(stores == null) {
stores = new ArrayList<>();
} else {
stores.clear();
}
stores.addAll(call.execute());
System.out.println("stores "+ stores);
} catch (IOException e) {
e.printStackTrace();
}
}
}).get();
...
<强>更新强>
我没有意识到你(显然)正在使用Retrofit 2.我有机会尝试一下,这就是我想出来的。
这是我在app / build.gradle中的相关依赖项:
compile 'com.squareup.retrofit:retrofit:2.0.0-beta2'
compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2'
...这是我的API界面:
public interface Api {
@Headers("Accept: application/json")
@GET("/v2/567595ad0f0000ea23315d02")
public Call<List<Widget>> widgets();
}
...这是一个简单的DTO,我将把一些JSON解组为:
public class Widget {
public String value;
}
...最后,这是我的测试活动: 公共类Retrofit2TestActivity扩展了AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final Api mockyApi = new Retrofit.Builder()
.baseUrl("http://www.mocky.io")
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(Api.class);
mockyApi.widgets().enqueue(new Callback<List<Widget>>() {
@Override
public void onResponse(Response<List<Widget>> response, Retrofit retrofit) {
if(response.isSuccess()) {
Log.d(Retrofit2TestActivity.class.getName(), "## widgets.size() == " + response.body().size());
} else {
Log.d(Retrofit2TestActivity.class.getName(), String.format("## response was NOT successful [%d]", response.code()));
}
}
@Override
public void onFailure(Throwable t) {
Log.d(Retrofit2TestActivity.class.getName(), String.format("## response was NOT successful [%s]", t.getMessage()));
}
});
}
}
显然,您应该将Widget
替换为Store
类型。除此之外,操纵List<Store>
作为活动的正常成员变量应该是直截了当的。
我希望有所帮助。