Android:线程没有将数据传递给Handler

时间:2015-02-25 14:05:23

标签: java android multithreading

我正在开发一个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();
                    }
                }
            };
        }
    }

4 个答案:

答案 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

        }
    });