我正在开发一个Android项目,我必须连接到服务器,检索餐馆列表并在ListView中显示它。情况是应用程序启动时,为了测试,我启动另一个Intent并在其中运行一个线程。在线程内部,我正在从服务器检索数据,我想在ListView上显示它。但是应该获取数据并显示它的处理程序方法不起作用。 不幸的是,我没有错误来隔离和处理问题,并且因为在线程之间传递数据是一个核心功能,我在它之间调用的那么多方法中迷失了。请看看我做错了什么。
MainActivity类:
public class MyActivity extends Activity {
RestaurantServiceImpl restaurantService = new RestaurantServiceImpl();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button button = (Button) findViewById(R.id.standortermitteln);
//Below starts the new view
Intent listScreen = new Intent(getApplicationContext(),RestaurantList.class);
}
RestaurantList.java:
public class RestaurantList extends Activity {
String url1 = "http://192.168.178.40:8080/restaurant/listing";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.restos);
ListView listView = (ListView) findViewById(R.id.restaurantList);
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
Log.d("Are we in listRestaurants","Checking");
try {
RestTemplate restTemplate = new RestTemplate();
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setAccept(Collections.singletonList(new MediaType("application", "json")));
HttpEntity<?> requestEntity = new HttpEntity<Object>(requestHeaders);
restTemplate.getMessageConverters().add(new GsonHttpMessageConverter());
ResponseEntity<Restaurant[]> responseEntity = restTemplate.exchange(url1, HttpMethod.GET, requestEntity, Restaurant[].class);
Restaurant[] restaurantList = responseEntity.getBody();
for(Restaurant restaurant : restaurantList){
// I am able to print these messages,
Log.d(restaurant.getRestaurantName(), "Restaurant name");
}
} catch (Exception e) {
Log.d("We are in stacktrace",e.toString());
e.printStackTrace();
}
}
});
thread.setPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
// I am not reaching here to set the ListView
Handler messageHandler = new Handler(){
public void handleMessage(Message message){
try {
Restaurant[] restaurants = (Restaurant[]) message.obj;
for(Restaurant restaurant : restaurants){
Log.d(restaurant.getRestaurantName(), "Restaurant name");
}
if(restaurants.length<1){
Log.d("Restaurants from thread are empty"," check");
}
for(Restaurant restaurant : restaurants){
Log.d(restaurant.getRestaurantName(), "Restaurant name in messageHandler");
}
ArrayAdapter<Restaurant> adapter = new ArrayAdapter<>(getApplicationContext(),android.R.layout.simple_list_item_1,restaurants);
listView.setAdapter(adapter);
}catch (Exception e){
e.printStackTrace();
}
}
};
}
}
答案 0 :(得分:2)
将queueNewRestaurants(restaurantList);
添加到第一个帖子的末尾。
private static final int NEW_RESTAURANTS = 1;
public void queueNewRestaurants(Restaurant[] restaurants) {
android.os.Message message = messageHandler.obtainMessage(
NEW_RESTAURANTS,
restaurants
);
message.sendToTarget();
}
答案 1 :(得分:0)
当您从线程向处理程序发送消息时,它不会调用处理程序。将以下行添加到您的主题中。
handleMessage.sendMessage(new Message());
修改强>
添加对象
Message message =new Message();
message.obj=arrayobject;
答案 2 :(得分:0)
您正在创建处理程序,但从不向其发送任何内容。在这种情况下,我建议您在工作线程中使用restaurantList后,将runnable发布到您正在构建的活动的一部分创建的Handler,或者使用runOnUiThread。
选项1。
public class RestaurantList extends Activity {
String url1 = "http://192.168.178.40:8080/restaurant/listing";
Handler mHandler = new Handler();
...
...
...
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
...
...
...
final Restaurant[] restaurantList = responseEntity.getBody();
mHandler.post(new Runnable() {
public void run() {
// update UI here
}
});
选项2。
致电
runOnUiThread(new Runnable(.....));
而不是mHandler.post(.....)
选项3。
使用AsyncTask,在doInBackground()中执行HTTP工作,并在onPostExecute()中更新UI。使用AsyncTask,您根本不必关心创建任何线程,它已为您完成。
在这种特殊情况下,我可能会选择选项3。
答案 3 :(得分:0)
除Handler
外,您还可以在线程run()
中使用java API:
runOnUiThread(new Runnable() {
public void run() {
//communicate with main thread here, send the result data to main thread
}
});