带有viewpager片段的标签,在错误的上下文中工作?

时间:2014-06-30 20:22:22

标签: android android-fragments achartengine

问题:

根据我的理解,我尝试在(工作人员?)chartview

中更新activity之外的thread
  

(GraphicalView chartView =   ChartFactory.getLineChartView(getActivity(),dataSet,mRenderer);)

我使用WeatherLib作为library来接收天气数据。 谁知道我哪里出错?

代码:

import android.app.Fragment;
import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.LinearLayout;

import com.survivingwithandroid.weather.lib.WeatherClient;
import com.survivingwithandroid.weather.lib.WeatherConfig;
import com.survivingwithandroid.weather.lib.exception.WeatherLibException;
import com.survivingwithandroid.weather.lib.exception.WeatherProviderInstantiationException;
import com.survivingwithandroid.weather.lib.model.DayForecast;
import com.survivingwithandroid.weather.lib.model.HourForecast;
import com.survivingwithandroid.weather.lib.model.WeatherHourForecast;
import com.survivingwithandroid.weather.lib.provider.IWeatherProvider;
import com.survivingwithandroid.weather.lib.provider.WeatherProviderFactory;
import com.survivingwithandroid.weather.lib.provider.openweathermap.OpenweathermapProviderType;
import com.survivingwithandroid.weather.lib.request.WeatherRequest;

import org.achartengine.ChartFactory;
import org.achartengine.GraphicalView;
import org.achartengine.chart.BarChart;
import org.achartengine.chart.PointStyle;
import org.achartengine.model.RangeCategorySeries;
import org.achartengine.model.XYMultipleSeriesDataset;
import org.achartengine.model.XYSeries;
import org.achartengine.renderer.XYMultipleSeriesRenderer;
import org.achartengine.renderer.XYSeriesRenderer;

import java.util.List;
import java.util.Locale;

public class ChartWeatherFragment extends Fragment {

    private LinearLayout chartLyt;
    private View v;
    private Animation fadeAnim;

    // London, UK
    private static final String CITY_ID = "2643743";

    private WeatherClient client;
    private List<DayForecast> dayForecast;
    private List<HourForecast> nextHourForecast;

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        fadeAnim = AnimationUtils.loadAnimation(getActivity(), R.anim.fade_anim);
        getData();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        v = inflater.inflate(R.layout.fragment_chart, container, false);
        chartLyt = (LinearLayout) v.findViewById(R.id.chart);
        return v;
    }

    private void getData() {

        Log.d("ChartWeatherFragment", "getData method");

        final WeatherClient.ClientBuilder builder = new WeatherClient.ClientBuilder();

        WeatherConfig config = new WeatherConfig();
        config.lang = Locale.getDefault().getLanguage();
        config.maxResult = 5;
        config.numDays = 5;
        config.unitSystem = WeatherConfig.UNIT_SYSTEM.M;

        // Forecast IO API key
        // config.ApiKey = "6396685aea23558da6383a01d9725666";

        // Open Weather map API key
        config.ApiKey = "#####################################";

        try {
            client = builder.attach(getActivity())
                    .provider(new OpenweathermapProviderType())
                    .httpClient(com.survivingwithandroid.weather.lib.client.okhttp.
                            WeatherDefaultClient.class)
                    .config(config)
                    .build();
        } catch (WeatherProviderInstantiationException e) {
            e.printStackTrace();
        }

        client.getHourForecastWeather(new WeatherRequest(CITY_ID), new WeatherClient.HourForecastWeatherEventListener() {
            @Override
            public void onWeatherRetrieved(WeatherHourForecast weatherHourForecast) {
                nextHourForecast = weatherHourForecast.getHourForecast();
                chartLyt.addView(createTempGraph(), 0);
            }

            @Override
            public void onWeatherError(WeatherLibException e) {
                e.printStackTrace();
            }

            @Override
            public void onConnectionError(Throwable t) {
                t.printStackTrace();
            }
        });
    }

    private View createTempGraph() {
        // We start creating the XYSeries to plot the temperature
        XYSeries series = new XYSeries("London Temperature hourly");

        // We start filling the series
        int hour = 0;
        for (HourForecast hf : nextHourForecast) {
            series.add(hour++, hf.weather.temperature.getTemp());
        }

        // Now we create the renderer
        XYSeriesRenderer renderer = new XYSeriesRenderer();
        renderer.setLineWidth(2);
        renderer.setColor(Color.RED);
        // Include low and max value
        renderer.setDisplayBoundingPoints(true);
        // we add point markers
        renderer.setPointStyle(PointStyle.CIRCLE);
        renderer.setPointStrokeWidth(3);


        // Now we add our series
        XYMultipleSeriesDataset dataSet = new XYMultipleSeriesDataset();
        dataSet.addSeries(series);

        // Finaly we create the multiple series renderer to control the graph
        XYMultipleSeriesRenderer mRenderer = new XYMultipleSeriesRenderer();
        mRenderer.addSeriesRenderer(renderer);

        // We want to avoid black border
        mRenderer.setMarginsColor(Color.argb(0x00, 0xff, 0x00, 0x00));
        // Disable Pan on two axis
        mRenderer.setPanEnabled(false, false);
        mRenderer.setYAxisMax(35);
        mRenderer.setYAxisMin(0);
        mRenderer.setShowGrid(true); // we show the grid
        GraphicalView chartView = ChartFactory.getLineChartView(getActivity(), dataSet, mRenderer);

        // Enable chart click
        mRenderer.setClickEnabled(true);
        return chartView;
    }
}

堆栈跟踪:

06-30 20:24:44.012    1903-1903/nl.inversion.weatherapp D/ChartWeatherFragment﹕ getData method
06-30 20:24:44.012    1903-1903/nl.inversion.weatherapp D/SwA﹕ Client [com.survivingwithandroid.weather.lib.client.okhttp.WeatherDefaultClient@b40a4ac8]
06-30 20:24:44.052    1903-1903/nl.inversion.weatherapp D/dalvikvm﹕ GC_FOR_ALLOC freed 220K, 10% free 3400K/3740K, paused 3ms, total 4ms
06-30 20:24:44.092    1903-1920/nl.inversion.weatherapp W/dalvikvm﹕ VFY: unable to find class referenced in signature (Ljava/nio/file/Path;)
06-30 20:24:44.092    1903-1920/nl.inversion.weatherapp W/dalvikvm﹕ VFY: unable to find class referenced in signature ([Ljava/nio/file/OpenOption;)
06-30 20:24:44.092    1903-1920/nl.inversion.weatherapp I/dalvikvm﹕ Could not find method java.nio.file.Files.newOutputStream, referenced from method okio.Okio.sink
06-30 20:24:44.092    1903-1920/nl.inversion.weatherapp W/dalvikvm﹕ VFY: unable to resolve static method 8451: Ljava/nio/file/Files;.newOutputStream (Ljava/nio/file/Path;[Ljava/nio/file/OpenOption;)Ljava/io/OutputStream;
06-30 20:24:44.092    1903-1920/nl.inversion.weatherapp D/dalvikvm﹕ VFY: replacing opcode 0x71 at 0x000a
06-30 20:24:44.092    1903-1920/nl.inversion.weatherapp W/dalvikvm﹕ VFY: unable to find class referenced in signature (Ljava/nio/file/Path;)
06-30 20:24:44.092    1903-1920/nl.inversion.weatherapp W/dalvikvm﹕ VFY: unable to find class referenced in signature ([Ljava/nio/file/OpenOption;)
06-30 20:24:44.092    1903-1920/nl.inversion.weatherapp I/dalvikvm﹕ Could not find method java.nio.file.Files.newInputStream, referenced from method okio.Okio.source
06-30 20:24:44.092    1903-1920/nl.inversion.weatherapp W/dalvikvm﹕ VFY: unable to resolve static method 8450: Ljava/nio/file/Files;.newInputStream (Ljava/nio/file/Path;[Ljava/nio/file/OpenOption;)Ljava/io/InputStream;
06-30 20:24:44.092    1903-1920/nl.inversion.weatherapp D/dalvikvm﹕ VFY: replacing opcode 0x71 at 0x000a
06-30 20:24:44.302    1903-1920/nl.inversion.weatherapp D/dalvikvm﹕ GC_FOR_ALLOC freed 386K, 13% free 3525K/4032K, paused 2ms, total 2ms
06-30 20:24:44.302    1903-1920/nl.inversion.weatherapp W/dalvikvm﹕ threadid=11: thread exiting with uncaught exception (group=0xb3d2db20)
06-30 20:24:44.302    1903-1920/nl.inversion.weatherapp E/AndroidRuntime﹕ FATAL EXCEPTION: OkHttp Dispatcher
    Process: nl.inversion.weatherapp, PID: 1903
    java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
            at android.os.Handler.<init>(Handler.java:200)
            at android.os.Handler.<init>(Handler.java:114)
            at org.achartengine.GraphicalView.<init>(GraphicalView.java:93)
            at org.achartengine.ChartFactory.getLineChartView(ChartFactory.java:71)
            at nl.inversion.weatherapp.ChartWeatherFragment.createTempGraph(ChartWeatherFragment.java:152)
            at nl.inversion.weatherapp.ChartWeatherFragment.access$100(ChartWeatherFragment.java:40)
            at nl.inversion.weatherapp.ChartWeatherFragment$1.onWeatherRetrieved(ChartWeatherFragment.java:101)
            at com.survivingwithandroid.weather.lib.client.okhttp.WeatherDefaultClient$6.onResponse(WeatherDefaultClient.java:381)
            at com.squareup.okhttp.Call$AsyncCall.execute(Call.java:150)
            at com.squareup.okhttp.internal.NamedRunnable.run(NamedRunnable.java:33)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
            at java.lang.Thread.run(Thread.java:841)

更新,问题已解决

感谢

由于我无法使用Activity.runOnUiThread(new Runnable()),我现在正在使用似乎有效的处理程序。感谢名单!

代码snippit:

 client.getHourForecastWeather(new WeatherRequest(cityId),
            new WeatherClient.HourForecastWeatherEventListener() {
                @Override
                public void onWeatherRetrieved(WeatherHourForecast weatherHourForecast) {
                    nextHourForecast = weatherHourForecast.getHourForecast();

                    /* Update UI
                    * Since callback is invoked on a background worker thread, create a handler
                    * to update the layout in the main UI thread
                    */
                    Handler handler = new Handler(Looper.getMainLooper());
                    handler.post(new Runnable() {
                        public void run() {
                            chartLyt.addView(createTempGraph(), 0);
                        }
                    });
                }

                @Override
                public void onWeatherError(WeatherLibException e) {
                    e.printStackTrace();
                }

                @Override
                public void onConnectionError(Throwable t) {
                    t.printStackTrace();
                }
            });

1 个答案:

答案 0 :(得分:3)

是的,在后台工作线程上调用onWeatherRetrieved()回调。您只能在主UI线程上触摸UI小部件,因此只能触摸异常。

使用例如Activity runOnUiThread()发布要在主UI线程上运行的Runnable