doInBackground 方法中的 ArrayIndexOutOfBoundsException
ArrayIndexOutOfBoundsException in doInBackground method
请帮我解决这个错误。即使在 execute() 方法中传递值后,我仍然无法解决此问题。
Caused by: java.lang.ArrayIndexOutOfBoundsException: length=0; index=0
at com.iamsharzil.constraintlayoutproject.DownloadNews.doInBackground(DownloadNews.java:54)
at com.iamsharzil.constraintlayoutproject.DownloadNews.doInBackground(DownloadNews.java:22)
DownloadNews.java
String NEWS_SOURCE = "bbc-news";
ArrayList<HashMap<String, String>> dataList = new ArrayList<HashMap<String, String>>();
private Activity mContext;
String API_KEY = "4f5f4fbf57f7476ba41c276b28379a6b";
ListView listNews;
static final String KEY_AUTHOR = "author";
static final String KEY_TITLE = "title";
static final String KEY_DESCRIPTION = "description";
static final String KEY_URL = "url";
static final String KEY_URLTOIMAGE = "urlToImage";
static final String KEY_PUBLISHEDAT = "publishedAt";
public DownloadNews(BaseDrawerActivity mContext) {
this.mContext = mContext;
Log.i("Constructor", "Download News called");
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
protected String doInBackground(String... args) {
String xml = "";
String url = args[0];
Log.i("URL", url);
xml = Function.executeGet(url);
return xml;
}
@Override
protected void onPostExecute(String xml) {
if(null != xml && xml.length()>10) {
try {
JSONObject jsonResponse = new JSONObject(xml);
JSONArray jsonArray = jsonResponse.optJSONArray("articles");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
HashMap<String, String> map = new HashMap<String, String>();
map.put(KEY_AUTHOR, jsonObject.optString(KEY_AUTHOR).toString());
map.put(KEY_TITLE, jsonObject.optString(KEY_TITLE).toString());
map.put(KEY_DESCRIPTION, jsonObject.optString(KEY_DESCRIPTION).toString());
map.put(KEY_URL, jsonObject.optString(KEY_URL).toString());
map.put(KEY_URLTOIMAGE, jsonObject.optString(KEY_URLTOIMAGE).toString());
map.put(KEY_PUBLISHEDAT, jsonObject.optString(KEY_PUBLISHEDAT).toString());
dataList.add(map);
}
} catch (JSONException e) {
Toast.makeText(mContext, "Unexpected error", Toast.LENGTH_SHORT).show();
}
listNews = (ListView) mContext.findViewById(R.id.listNews);
ListNewsAdapter adapter = new ListNewsAdapter((Activity) mContext, dataList);
listNews.setAdapter(adapter);
listNews.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Intent i = new Intent(mContext, DetailsActivity.class);
i.putExtra("url", dataList.get(+position).get(KEY_URL));
mContext.startActivity(i);
}
});
}else{
Toast.makeText(mContext, "No news found", Toast.LENGTH_SHORT).show();
}
}
}
BaseDrawerActivity.java
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_base_drawer);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
toolbar.setTitle("NEWS");
listNews = (ListView) findViewById(R.id.listNews);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
if(Function.isNetworkAvailable(getApplicationContext()))
{
DownloadNews newsTask = new DownloadNews(this);
newsTask.execute();
}else{
Toast.makeText(getApplicationContext(), "No Internet Connection", Toast.LENGTH_LONG).show();
}
}
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
Fragment fragment = null;
if (id == R.id.nav_general) {
String general = "https://newsapi.org/v2/top-headlines?country=in&apiKey=" + API_KEY;
new DownloadNews(this).execute(general);
} else if (id == R.id.nav_sports) {
String sports = "https://newsapi.org/v2/top-headlines?categoty=sports&country=in&apiKey=" + API_KEY;
new DownloadNews(this).execute(sports);
} else if (id == R.id.nav_business) {
String business = "https://newsapi.org/v2/top-headlines?categoty=business&country=in&apiKey=" + API_KEY;
new DownloadNews(this).execute(business);
} else if (id == R.id.nav_technology) {
String technology = "https://newsapi.org/v2/top-headlines?categoty=technology&country=in&apiKey=" + API_KEY;
new DownloadNews(this).execute(technology);
} else if (id == R.id.nav_entertainment) {
String entertainment = "https://newsapi.org/v2/top-headlines?categoty=entertainment&country=in&apiKey=" + API_KEY;
new DownloadNews(this).execute(entertainment);
} else if (id == R.id.nav_health) {
String health = "https://newsapi.org/v2/top-headlines?categoty=health&country=in&apiKey=" + API_KEY;
new DownloadNews(this).execute(health);
} else if (id == R.id.nav_science) {
String science = "https://newsapi.org/v2/top-headlines?categoty=science&country=in&apiKey=" + API_KEY;
new DownloadNews(this).execute(science);
}
if(fragment!=null) {
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.screen_area, fragment);
ft.commit();
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
当用户单击任何我希望更改的菜单项时 url。
Function.java
public class Function {
public static boolean isNetworkAvailable(Context context) {
return ((ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE)).
getActiveNetworkInfo()!=null;
}
public static String executeGet(String targetURL) {
URL url;
HttpURLConnection connection = null;
try {
//Create connection
url = new URL(targetURL);
connection = (HttpURLConnection)url.openConnection();
//connection.setRequestMethod("POST");
//connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("content-type", "application/json; charset=utf-8");
connection.setRequestProperty("Content-Language", "en-US");
connection.setUseCaches (false);
connection.setDoInput(true);
connection.setDoOutput(false);
InputStream is;
int status = connection.getResponseCode();
if (status != HttpURLConnection.HTTP_OK)
is = connection.getErrorStream();
else
is = connection.getInputStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
String line;
StringBuffer response = new StringBuffer();
while((line = rd.readLine()) != null) {
response.append(line);
response.append('\r');
}
rd.close();
return response.toString();
} catch (Exception e) {
return null;
} finally {
if(connection != null) {
connection.disconnect();
}
}
}
}
你在这里调用执行:
if(Function.isNetworkAvailable(getApplicationContext()))
{
DownloadNews newsTask = new DownloadNews(this);
newsTask.execute(); // <-
}else{
Toast.makeText(getApplicationContext(), "No Internet Connection", Toast.LENGTH_LONG).show();
}
但不传递参数。这将导致您的方法失败,因为您无法访问零长度数组的第零项。您要么需要确保始终向其传递数据,要么需要执行以下操作:
protected String doInBackground(String... args) {
String xml = "";
if (args.length > 0) {
String url = args[0];
Log.i("URL", url);
xml = Function.executeGet(url);
}
return xml;
}
这样,如果 args
为空,您 return 一个空字符串,然后可以在需要的地方处理它。
根据 how to call async task with different url 和@Justin-Pearce 的回答,我能够解决错误。
BaseDrawerActivity.java
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
Fragment fragment = null;
String general = null, health = null, sports = null, business = null, technology = null, science = null, entertainment = null;
if (id == R.id.nav_general) {
general = "https://newsapi.org/v2/top-headlines?country=in&pageSize=100&apiKey=" + API_KEY;
} else if (id == R.id.nav_sports) {
sports = "https://newsapi.org/v2/top-headlines?country=in&category=sports&pageSize=100&apiKey=" + API_KEY;
} else if (id == R.id.nav_business) {
business = "https://newsapi.org/v2/top-headlines?country=in&category=business&pageSize=100&apiKey=" + API_KEY;
} else if (id == R.id.nav_technology) {
technology = "https://newsapi.org/v2/top-headlines?country=in&category=technology&pageSize=100&apiKey=" + API_KEY;
} else if (id == R.id.nav_entertainment) {
entertainment = "https://newsapi.org/v2/top-headlines?country=in&category=entertainment&pageSize=100&apiKey=" + API_KEY;
} else if (id == R.id.nav_health) {
health = "https://newsapi.org/v2/top-headlines?country=in&category=health&pageSize=100&apiKey=" + API_KEY;
} else if (id == R.id.nav_science) {
science = "https://newsapi.org/v2/top-headlines?country=in&category=science&pageSize=100&apiKey=" + API_KEY;
}
new DownloadNews(this).execute(
general,
sports,
business,
technology,
entertainment,
health,
science);
if(fragment!=null) {
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.screen_area, fragment);
ft.commit();
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
DownloadNews.java
@Override
protected void onPreExecute() {
super.onPreExecute();
}
protected String doInBackground(String... args) {
String xml = "";
for(String urls: args) {
try {
String u = new String(urls);
xml = Function.executeGet(u);
Log.i("args length", String.valueOf(args.length));
Log.i("URL", u);
} catch (Exception e) {}
}
return xml;
}
请帮我解决这个错误。即使在 execute() 方法中传递值后,我仍然无法解决此问题。
Caused by: java.lang.ArrayIndexOutOfBoundsException: length=0; index=0 at com.iamsharzil.constraintlayoutproject.DownloadNews.doInBackground(DownloadNews.java:54) at com.iamsharzil.constraintlayoutproject.DownloadNews.doInBackground(DownloadNews.java:22)
DownloadNews.java
String NEWS_SOURCE = "bbc-news";
ArrayList<HashMap<String, String>> dataList = new ArrayList<HashMap<String, String>>();
private Activity mContext;
String API_KEY = "4f5f4fbf57f7476ba41c276b28379a6b";
ListView listNews;
static final String KEY_AUTHOR = "author";
static final String KEY_TITLE = "title";
static final String KEY_DESCRIPTION = "description";
static final String KEY_URL = "url";
static final String KEY_URLTOIMAGE = "urlToImage";
static final String KEY_PUBLISHEDAT = "publishedAt";
public DownloadNews(BaseDrawerActivity mContext) {
this.mContext = mContext;
Log.i("Constructor", "Download News called");
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
protected String doInBackground(String... args) {
String xml = "";
String url = args[0];
Log.i("URL", url);
xml = Function.executeGet(url);
return xml;
}
@Override
protected void onPostExecute(String xml) {
if(null != xml && xml.length()>10) {
try {
JSONObject jsonResponse = new JSONObject(xml);
JSONArray jsonArray = jsonResponse.optJSONArray("articles");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
HashMap<String, String> map = new HashMap<String, String>();
map.put(KEY_AUTHOR, jsonObject.optString(KEY_AUTHOR).toString());
map.put(KEY_TITLE, jsonObject.optString(KEY_TITLE).toString());
map.put(KEY_DESCRIPTION, jsonObject.optString(KEY_DESCRIPTION).toString());
map.put(KEY_URL, jsonObject.optString(KEY_URL).toString());
map.put(KEY_URLTOIMAGE, jsonObject.optString(KEY_URLTOIMAGE).toString());
map.put(KEY_PUBLISHEDAT, jsonObject.optString(KEY_PUBLISHEDAT).toString());
dataList.add(map);
}
} catch (JSONException e) {
Toast.makeText(mContext, "Unexpected error", Toast.LENGTH_SHORT).show();
}
listNews = (ListView) mContext.findViewById(R.id.listNews);
ListNewsAdapter adapter = new ListNewsAdapter((Activity) mContext, dataList);
listNews.setAdapter(adapter);
listNews.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Intent i = new Intent(mContext, DetailsActivity.class);
i.putExtra("url", dataList.get(+position).get(KEY_URL));
mContext.startActivity(i);
}
});
}else{
Toast.makeText(mContext, "No news found", Toast.LENGTH_SHORT).show();
}
}
}
BaseDrawerActivity.java
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_base_drawer);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
toolbar.setTitle("NEWS");
listNews = (ListView) findViewById(R.id.listNews);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
if(Function.isNetworkAvailable(getApplicationContext()))
{
DownloadNews newsTask = new DownloadNews(this);
newsTask.execute();
}else{
Toast.makeText(getApplicationContext(), "No Internet Connection", Toast.LENGTH_LONG).show();
}
}
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
Fragment fragment = null;
if (id == R.id.nav_general) {
String general = "https://newsapi.org/v2/top-headlines?country=in&apiKey=" + API_KEY;
new DownloadNews(this).execute(general);
} else if (id == R.id.nav_sports) {
String sports = "https://newsapi.org/v2/top-headlines?categoty=sports&country=in&apiKey=" + API_KEY;
new DownloadNews(this).execute(sports);
} else if (id == R.id.nav_business) {
String business = "https://newsapi.org/v2/top-headlines?categoty=business&country=in&apiKey=" + API_KEY;
new DownloadNews(this).execute(business);
} else if (id == R.id.nav_technology) {
String technology = "https://newsapi.org/v2/top-headlines?categoty=technology&country=in&apiKey=" + API_KEY;
new DownloadNews(this).execute(technology);
} else if (id == R.id.nav_entertainment) {
String entertainment = "https://newsapi.org/v2/top-headlines?categoty=entertainment&country=in&apiKey=" + API_KEY;
new DownloadNews(this).execute(entertainment);
} else if (id == R.id.nav_health) {
String health = "https://newsapi.org/v2/top-headlines?categoty=health&country=in&apiKey=" + API_KEY;
new DownloadNews(this).execute(health);
} else if (id == R.id.nav_science) {
String science = "https://newsapi.org/v2/top-headlines?categoty=science&country=in&apiKey=" + API_KEY;
new DownloadNews(this).execute(science);
}
if(fragment!=null) {
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.screen_area, fragment);
ft.commit();
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
当用户单击任何我希望更改的菜单项时 url。
Function.java
public class Function {
public static boolean isNetworkAvailable(Context context) {
return ((ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE)).
getActiveNetworkInfo()!=null;
}
public static String executeGet(String targetURL) {
URL url;
HttpURLConnection connection = null;
try {
//Create connection
url = new URL(targetURL);
connection = (HttpURLConnection)url.openConnection();
//connection.setRequestMethod("POST");
//connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("content-type", "application/json; charset=utf-8");
connection.setRequestProperty("Content-Language", "en-US");
connection.setUseCaches (false);
connection.setDoInput(true);
connection.setDoOutput(false);
InputStream is;
int status = connection.getResponseCode();
if (status != HttpURLConnection.HTTP_OK)
is = connection.getErrorStream();
else
is = connection.getInputStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
String line;
StringBuffer response = new StringBuffer();
while((line = rd.readLine()) != null) {
response.append(line);
response.append('\r');
}
rd.close();
return response.toString();
} catch (Exception e) {
return null;
} finally {
if(connection != null) {
connection.disconnect();
}
}
}
}
你在这里调用执行:
if(Function.isNetworkAvailable(getApplicationContext()))
{
DownloadNews newsTask = new DownloadNews(this);
newsTask.execute(); // <-
}else{
Toast.makeText(getApplicationContext(), "No Internet Connection", Toast.LENGTH_LONG).show();
}
但不传递参数。这将导致您的方法失败,因为您无法访问零长度数组的第零项。您要么需要确保始终向其传递数据,要么需要执行以下操作:
protected String doInBackground(String... args) {
String xml = "";
if (args.length > 0) {
String url = args[0];
Log.i("URL", url);
xml = Function.executeGet(url);
}
return xml;
}
这样,如果 args
为空,您 return 一个空字符串,然后可以在需要的地方处理它。
根据 how to call async task with different url 和@Justin-Pearce 的回答,我能够解决错误。
BaseDrawerActivity.java
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
Fragment fragment = null;
String general = null, health = null, sports = null, business = null, technology = null, science = null, entertainment = null;
if (id == R.id.nav_general) {
general = "https://newsapi.org/v2/top-headlines?country=in&pageSize=100&apiKey=" + API_KEY;
} else if (id == R.id.nav_sports) {
sports = "https://newsapi.org/v2/top-headlines?country=in&category=sports&pageSize=100&apiKey=" + API_KEY;
} else if (id == R.id.nav_business) {
business = "https://newsapi.org/v2/top-headlines?country=in&category=business&pageSize=100&apiKey=" + API_KEY;
} else if (id == R.id.nav_technology) {
technology = "https://newsapi.org/v2/top-headlines?country=in&category=technology&pageSize=100&apiKey=" + API_KEY;
} else if (id == R.id.nav_entertainment) {
entertainment = "https://newsapi.org/v2/top-headlines?country=in&category=entertainment&pageSize=100&apiKey=" + API_KEY;
} else if (id == R.id.nav_health) {
health = "https://newsapi.org/v2/top-headlines?country=in&category=health&pageSize=100&apiKey=" + API_KEY;
} else if (id == R.id.nav_science) {
science = "https://newsapi.org/v2/top-headlines?country=in&category=science&pageSize=100&apiKey=" + API_KEY;
}
new DownloadNews(this).execute(
general,
sports,
business,
technology,
entertainment,
health,
science);
if(fragment!=null) {
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.screen_area, fragment);
ft.commit();
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
DownloadNews.java
@Override
protected void onPreExecute() {
super.onPreExecute();
}
protected String doInBackground(String... args) {
String xml = "";
for(String urls: args) {
try {
String u = new String(urls);
xml = Function.executeGet(u);
Log.i("args length", String.valueOf(args.length));
Log.i("URL", u);
} catch (Exception e) {}
}
return xml;
}