简体   繁体   English

Android 4.0中的类无响应-在2.3及以下版本中有效

[英]No response from class in Android 4.0 - works in 2.3 and below

I've got a class, GetWeather.java, which fetches weather data from an API. 我有一个类GetWeather.java,它从API提取天气数据。 It is called from the main activity of my app periodically via a separate thread. 在我的应用程序的主要活动中,它是通过一个单独的线程定期调用的。 The thread hits the GetWeather class and posts the returned data to a TextView. 该线程命中GetWeather类,并将返回的数据发布到TextView。

In either case a System.out.println of the returned data from within the GetWeather class shows that the data is indeed being returned. 无论哪种情况,从GetWeather类中返回的数据的System.out.println都表明确实在返回数据。

Below is GetWeather.java: 以下是GetWeather.java:

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.net.Uri;
import android.util.Log;

public class GetWeather {

    InputStream is = null;

    JSONArray jArray = null;
    JSONObject json_data = new JSONObject();
    String result = "";

    String strTemp = "";
    String strWindSpeed = "";
    String strWindDir = "";
    String strVisibility = "";

    String strPosition = "";

    public static final Uri KEY_121 = Uri.parse("http://api.worldweatheronline.com/free/v1/weather.ashx");
    String strWeatherApiKey = "REMOVED";

    public GetWeather(String Location) {
        strPosition = Location;
    }

    public void returnWeather() {
        try {
            HttpClient httpclient = new DefaultHttpClient();

            HttpPost httppost = new HttpPost(KEY_121 + "?key="
                    + strWeatherApiKey + "&q=" + strPosition + "&format=json");

            HttpResponse response = httpclient.execute(httppost);
            HttpEntity entity = response.getEntity();
            is = entity.getContent();

        } catch (Exception e) {
            Log.e("log_tag", "Error in http connection " + e.toString());
        }

        // convert response to string
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    is, "iso-8859-1"), 8);
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
            is.close();
            result = sb.toString();

        } catch (Exception e) {
            Log.e("log_tag", "Error converting result " + e.toString());
        }
        // parse json data
        try {
            JSONObject object = new JSONObject(result);
            JSONObject weather = object.getJSONObject("data");
            JSONArray current_conditions = weather
                    .getJSONArray("current_condition");
            for (int i = 0; i < current_conditions.length(); i++) {
                JSONObject object1 = (JSONObject) current_conditions.get(i);
                strTemp = object1.getString("temp_C");
                strWindSpeed = object1.getString("windspeedMiles");
                strWindDir = object1.getString("winddir16Point");
                strVisibility = object1.getString("visibility");

                // Testing output
                System.out.println(strTemp);
                System.out.println(strWindSpeed);
                System.out.println(strWindDir);
                System.out.println(strVisibility);
            }
        } catch (JSONException e) {
            Log.e("log_tag", "Error parsing data " + e.toString());
        }
    }
}

Here is the relevant code from the main activity: 这是主要活动中的相关代码:

Runnable updateConsoleRunnable = new Runnable() {
    public void run() {
        tvConsole.setMovementMethod(new ScrollingMovementMethod());
        tvConsole.setSelected(true);

        handler.postDelayed(this, TIME_DELAY);

        // Only display weather data while service is enabled
        if (isServiceRunning()) {
            GetWeather weather = new GetWeather(strPosition);
            weather.returnWeather();

            // Weather package
            tvConsole
                    .append("Weather Update\n-------------------\n\nCurrent Temp (C): "
                            + weather.strTemp
                            + "C\n"
                            + "Wind is out of the "
                            + weather.strWindDir
                            + " at "
                            + weather.strWindSpeed
                            + " MPH\n"
                            + "Visibility is "
                            + weather.strVisibility
                            + " miles\n\n");

            // Auto-scroll textview
            // Does not function on Android 4.0+
            final Layout layout = tvConsole.getLayout();
            if (layout != null) {
                int scrollDelta = layout.getLineBottom(tvConsole
                        .getLineCount() - 1)
                        - tvConsole.getScrollY()
                        - tvConsole.getHeight();
                if (scrollDelta > 0)
                    tvConsole.scrollBy(0, scrollDelta);
            }

        }

    }
};

As I mentioned previously, this works as expected in Gingerbread and FroYo , but ICS and JellyBean OS fail to see the variables set by GetWeather. 正如我前面提到的,这个工程预期在姜饼和FroYo ,但ICSJellyBean OS无法看到的GetWeather设置的变量。 I think, I read somewhere this has something to do with needing an AsyncTask, but I am not able to make-out heads or tails of it. 我想,我在某处读到这与需要AsyncTask有关,但我无法弄清它的正面还是反面。

Advance Thanks 提前谢谢

you cannot touch anything in the ui thread from a background thread, to do that use Handlers, initialize your background thread passing it a Handler object. 您不能从后台线程触摸ui线程中的任何内容,要使用Handlers进行初始化,请为您的后台线程初始化Handler对象。 When data arrives use the handler to send a message to the ui. 数据到达时,使用处理程序将消息发送到ui。 In the ui when the message from the background thread comes, just update the Views. 在ui中,当来自后台线程的消息到来时,只需更新视图。

Try to use async task like this, 尝试使用这样的异步任务,

In your main activity, 在您的主要活动中

public class GetWeather extends AsyncTask<Void, Integer, Void> {



    public GetWeather(Activity activity) {
        this.activity = activity;


        context = activity;
        dialog = new ProgressDialog(context);


    }

    /** progress dialog to show user that the backup is processing. */
    private ProgressDialog dialog;
    /** application context. */
    private Activity activity;
    private Context context;



    protected void onPreExecute() {
        // TODO Auto-generated method stub
        super.onPreExecute();






    }

    @Override
    protected Void doInBackground(Void... params) {
        // TODO Auto-generated method stub


        GetWeather weather = new GetWeather(strPosition);
        weather.returnWeather();


        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        // TODO Auto-generated method stub
        super.onPostExecute(result);



                     tvConsole
                .append("Weather Update\n-------------------\n\nCurrent Temp (C): "
                        + weather.strTemp
                        + "C\n"
                        + "Wind is out of the "
                        + weather.strWindDir
                        + " at "
                        + weather.strWindSpeed
                        + " MPH\n"
                        + "Visibility is "
                        + weather.strVisibility
                        + " miles\n\n");

        // Auto-scroll textview
        // Does not function on Android 4.0+
        final Layout layout = tvConsole.getLayout();
        if (layout != null) {
            int scrollDelta = layout.getLineBottom(tvConsole
                    .getLineCount() - 1)
                    - tvConsole.getScrollY()
                    - tvConsole.getHeight();
            if (scrollDelta > 0)
                tvConsole.scrollBy(0, scrollDelta);
        }




                     }



  }

And call it like, 并这样称呼它,

new GetWeather(Mainactivity.this).execute();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM