如何在导航抽屉中使用asynctask。当前代码给出了这个错误:
09-07 13:20:31.835:E / AndroidRuntime(7893):致命异常:AsyncTask#1 09-07 13:20:31.835:E / AndroidRuntime(7893):java.lang.RuntimeException:执行doInBackground()时发生错误
这是我的主要活动:
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
答案 0 :(得分: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);