java - 带抽屉导航的异步任务

标签 java android android-fragments android-asynctask weather

如何将异步任务与抽屉导航一起使用。当前代码给我这个错误:

09-07 13:20:31.835: E/AndroidRuntime(7893): FATAL EXCEPTION: AsyncTask #1 09-07 13:20:31.835: E/AndroidRuntime(7893): java.lang.RuntimeException: An error occured while executing doInBackground()

这是我的主要 Activity :

public class MainActivity extends Activity {
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private ActionBarDrawerToggle mDrawerToggle;

private CharSequence mDrawerTitle;
private CharSequence mTitle;
private String[] mPlanetTitles;
private static TextView cityText;
private static TextView condDescr;
private static TextView temp;
private static TextView press;
private static TextView windSpeed;
private static TextView windDeg;

private static TextView hum;
private static ImageView imgView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    final String ARG_PLANET_NUMBER = "planet_number";
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mTitle = mDrawerTitle = getTitle();
    mPlanetTitles = getResources().getStringArray(R.array.planets_array);
    mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
    mDrawerList = (ListView) findViewById(R.id.left_drawer);


    mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);

    mDrawerList.setAdapter(new ArrayAdapter<String>(this,
            R.layout.drawer_list_item, mPlanetTitles));
    mDrawerList.setOnItemClickListener(new DrawerItemClickListener());


    getActionBar().setDisplayHomeAsUpEnabled(true);
    getActionBar().setHomeButtonEnabled(true);


    mDrawerToggle = new ActionBarDrawerToggle(
            this,                  /* host Activity */
            mDrawerLayout,         /* DrawerLayout object */
            R.drawable.ic_drawer,  /* nav drawer image to replace 'Up' caret */
            R.string.drawer_open,  /* "open drawer" description for accessibility */
            R.string.drawer_close  /* "close drawer" description for accessibility */
            ) {
        public void onDrawerClosed(View view) {
            getActionBar().setTitle(mTitle);
            invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
        }

        public void onDrawerOpened(View drawerView) {
            getActionBar().setTitle(mDrawerTitle);
            invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
        }
    };
    mDrawerLayout.setDrawerListener(mDrawerToggle);

    if (savedInstanceState == null) {
        selectItem(0);
    }
    int i = Integer.parseInt(ARG_PLANET_NUMBER);
    String planet = getResources().getStringArray(R.array.planets_array)[i];
    JSONWeatherTask task = new JSONWeatherTask();
    task.execute(new String[]{planet});
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.main, menu);
    return super.onCreateOptionsMenu(menu);
}


@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
    menu.findItem(R.id.action_websearch).setVisible(!drawerOpen);
    return super.onPrepareOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    if (mDrawerToggle.onOptionsItemSelected(item)) {
        return true;
    }

    switch(item.getItemId()) {
    case R.id.action_websearch:

        Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
        intent.putExtra(SearchManager.QUERY, getActionBar().getTitle());

        if (intent.resolveActivity(getPackageManager()) != null) {
            startActivity(intent);
        } else {
            Toast.makeText(this, R.string.app_not_available, Toast.LENGTH_LONG).show();
        }
        return true;
    default:
        return super.onOptionsItemSelected(item);
    }
}


private class DrawerItemClickListener implements ListView.OnItemClickListener {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        selectItem(position);
    }
}

private void selectItem(int position) {

    Fragment fragment = new WeatherNow();
    Bundle args = new Bundle();
    args.putInt(WeatherNow.ARG_PLANET_NUMBER, position);
    fragment.setArguments(args);

    FragmentManager fragmentManager = getFragmentManager();
    fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();


    mDrawerList.setItemChecked(position, true);
    setTitle(mPlanetTitles[position]);
    mDrawerLayout.closeDrawer(mDrawerList);
}

@Override
public void setTitle(CharSequence title) {
    mTitle = title;
    getActionBar().setTitle(mTitle);
}



@Override
protected void onPostCreate(Bundle savedInstanceState) {
    super.onPostCreate(savedInstanceState);
    // Sync the toggle state after onRestoreInstanceState has occurred.
    mDrawerToggle.syncState();
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    // Pass any configuration change to the drawer toggls
    mDrawerToggle.onConfigurationChanged(newConfig);
}


class JSONWeatherTask extends AsyncTask<String, Void, Weather> {

    @Override
    protected Weather doInBackground(String... params) {
        Weather weather = new Weather();
        String data = ( (new WeatherHttpClient()).getWeatherData(params[0], params[1]));

        try {
            weather = JSONWeatherParser.getWeather(data);
            System.out.println("Weather ["+weather+"]");
            // Let's retrieve the icon
            weather.iconData = ( (new WeatherHttpClient()).getImage(weather.currentCondition.getIcon()));

        } catch (JSONException e) {             
            e.printStackTrace();
        }
        return weather;

}


@Override
protected void onPostExecute(Weather weather) {         
        super.onPostExecute(weather);

        if (weather.iconData != null && weather.iconData.length > 0) {
            Bitmap img = BitmapFactory.decodeByteArray(weather.iconData, 0, weather.iconData.length); 
            imgView.setImageBitmap(img);
        }


        cityText.setText(weather.location.getCity() + "," + weather.location.getCountry());
        temp.setText("" + Math.round((weather.temperature.getTemp() - 275.15)));
        condDescr.setText(weather.currentCondition.getCondition() + "(" + weather.currentCondition.getDescr() + ")");   
    }

}

这是我的 WeatherNowFragment:

public class WeatherNow extends Fragment {
public static final String ARG_PLANET_NUMBER = "planet_number";
private static TextView cityText;
private static TextView condDescr;
private static TextView temp;
private static TextView press;
private static TextView windSpeed;
private static TextView windDeg;
private static TextView hum;
private static ImageView imgView;

public WeatherNow() {

}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.frag_main, container, false);
    int i = getArguments().getInt(ARG_PLANET_NUMBER);
    String planet = getResources().getStringArray(R.array.planets_array)[i];
    cityText = (TextView) rootView.findViewById(R.id.cityText);
    cityText.setText(planet);
    condDescr = (TextView) rootView.findViewById(R.id.condDescr);
    temp = (TextView) rootView.findViewById(R.id.temp);
    hum = (TextView) rootView.findViewById(R.id.hum);
    press = (TextView) rootView.findViewById(R.id.press);
    windSpeed = (TextView) rootView.findViewById(R.id.windSpeed);
    windDeg = (TextView) rootView.findViewById(R.id.windDeg);
    imgView = (ImageView) rootView.findViewById(R.id.condIcon);
    getActivity().setTitle(planet);


    return rootView;
}

JsonParser:

public class JSONWeatherParser {

public static Weather getWeather(String data) throws JSONException  {
    Weather weather = new Weather();

    // We create out JSONObject from the data
    JSONObject jObj = new JSONObject(data);

    // We start extracting the info
    Location loc = new Location();

    JSONObject coordObj = getObject("coord", jObj);
    loc.setLatitude(getFloat("lat", coordObj));
    loc.setLongitude(getFloat("lon", coordObj));

    JSONObject sysObj = getObject("sys", jObj);
    loc.setCountry(getString("country", sysObj));
    loc.setSunrise(getInt("sunrise", sysObj));
    loc.setSunset(getInt("sunset", sysObj));
    loc.setCity(getString("name", jObj));
    weather.location = loc;

    // We get weather info (This is an array)
    JSONArray jArr = jObj.getJSONArray("weather");

    // We use only the first value
    JSONObject JSONWeather = jArr.getJSONObject(0);
    weather.currentCondition.setWeatherId(getInt("id", JSONWeather));
    weather.currentCondition.setDescr(getString("description", JSONWeather));
    weather.currentCondition.setCondition(getString("main", JSONWeather));
    weather.currentCondition.setIcon(getString("icon", JSONWeather));

    JSONObject mainObj = getObject("main", jObj);
    weather.currentCondition.setHumidity(getInt("humidity", mainObj));
    weather.currentCondition.setPressure(getInt("pressure", mainObj));
    weather.temperature.setMaxTemp(getFloat("temp_max", mainObj));
    weather.temperature.setMinTemp(getFloat("temp_min", mainObj));
    weather.temperature.setTemp(getFloat("temp", mainObj));

    // Wind
    JSONObject wObj = getObject("wind", jObj);
    weather.wind.setSpeed(getFloat("speed", wObj));
    weather.wind.setDeg(getFloat("deg", wObj));

    // Clouds
    JSONObject cObj = getObject("clouds", jObj);
    weather.clouds.setPerc(getInt("all", cObj));

    // We download the icon to show


    return weather;
}


private static JSONObject getObject(String tagName, JSONObject jObj)  throws JSONException {
    JSONObject subObj = jObj.getJSONObject(tagName);
    return subObj;
}

private static String getString(String tagName, JSONObject jObj) throws JSONException {
    return jObj.getString(tagName);
}

private static float  getFloat(String tagName, JSONObject jObj) throws JSONException {
    return (float) jObj.getDouble(tagName);
}

private static int  getInt(String tagName, JSONObject jObj) throws JSONException {
    return jObj.getInt(tagName);
}

我是 android 和 java 编码的新手,并且已经坚持了一个星期左右,任何帮助将不胜感激!谢谢。

LOGCAT

09-07 15:02:46.381: E/AndroidRuntime(23029): FATAL EXCEPTION: AsyncTask #1
09-07 15:02:46.381: E/AndroidRuntime(23029): java.lang.RuntimeException: An error occured while executing doInBackground()
09-07 15:02:46.381: E/AndroidRuntime(23029):    at android.os.AsyncTask$3.done(AsyncTask.java:299)
09-07 15:02:46.381: E/AndroidRuntime(23029):    at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
09-07 15:02:46.381: E/AndroidRuntime(23029):    at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
09-07 15:02:46.381: E/AndroidRuntime(23029):    at java.util.concurrent.FutureTask.run(FutureTask.java:239)
09-07 15:02:46.381: E/AndroidRuntime(23029):    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
09-07 15:02:46.381: E/AndroidRuntime(23029):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
09-07 15:02:46.381: E/AndroidRuntime(23029):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
09-07 15:02:46.381: E/AndroidRuntime(23029):    at java.lang.Thread.run(Thread.java:856)
09-07 15:02:46.381: E/AndroidRuntime(23029): Caused by: java.lang.NullPointerException
09-07 15:02:46.381: E/AndroidRuntime(23029):    at org.json.JSONTokener.nextCleanInternal(JSONTokener.java:116)
09-07 15:02:46.381: E/AndroidRuntime(23029):    at org.json.JSONTokener.nextValue(JSONTokener.java:94)
09-07 15:02:46.381: E/AndroidRuntime(23029):    at org.json.JSONObject.<init>(JSONObject.java:154)
09-07 15:02:46.381: E/AndroidRuntime(23029):    at org.json.JSONObject.<init>(JSONObject.java:171)
09-07 15:02:46.381: E/AndroidRuntime(23029):    at com.data.reciever.JSONWeatherParser.getWeather(JSONWeatherParser.java:18)
09-07 15:02:46.381: E/AndroidRuntime(23029):    at com.activites.MainActivity$JSONWeatherTask.doInBackground(MainActivity.java:225)
09-07 15:02:46.381: E/AndroidRuntime(23029):    at com.activites.MainActivity$JSONWeatherTask.doInBackground(MainActivity.java:1)
09-07 15:02:46.381: E/AndroidRuntime(23029):    at android.os.AsyncTask$2.call(AsyncTask.java:287)
09-07 15:02:46.381: E/AndroidRuntime(23029):    at java.util.concurrent.FutureTask.run(FutureTask.java:234)
09-07 15:02:46.381: E/AndroidRuntime(23029):    ... 4 more

最佳答案

您的程序崩溃是因为您将只有 1 个元素的数组交给 AsyncTask。

但是在 doInBackground() 中您正在访问 params[1],这将导致 IndexOutOfBoundsException

String planet = getResources().getStringArray(R.array.planets_array)[i];
JSONWeatherTask task = new JSONWeatherTask();
task.execute(new String[]{planet});

在 doInBackground 内部:

String data = ( (new WeatherHttpClient()).getWeatherData(params[0], params[1]));

我建议您这样做

String [] planet = getResources().getStringArray(R.array.planets_array);
JSONWeatherTask task = new JSONWeatherTask();
task.execute(planet); 

关于java - 带抽屉导航的异步任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18671888/

相关文章:

android - DatePickerDialog 在屏幕旋转时保存布局

java - 将数据从 Activity 传递到 Fragment(通过从 Fragment 访问 Activity)给出 Class Cast Exception

java - 如何重用所有aws lambda函数中的代码?

java - MS SQL Server 2008 中的 JPA/Hibernate 分页错误映射到对象

java - 如何配置 Tomcat 以在出站连接中使用 TLS v1.2

未找到 androidx.lifecycle.DefaultLifecycleObserver

java - hadoop 单节点 jar 未运行

android - 从 Android 上的默认设置自定义标题 View

java - 如何在不丢帧的情况下将 ByteBuffer 转换为位图,反之亦然?

android - 如何在 Activity 关闭时触发重新加载?