- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试对正在查询的 URL 进行非常简单的更新。我根据选择的菜单项更改 onOptionsItemSelected 中的 URL。如果我选择第一项,该应用程序运行得很好。如果我选择第二项,应用程序就会崩溃。为什么?两个 URL 均已验证正确。我相信选择第二项(highestRated)会导致 NetworkOnMainThreadException。任何调试帮助将不胜感激。
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.mostPopular) {
FILM_REQUEST_URL = "http://api.themoviedb.org/3/movie/popular?api_key=[MyNetworkKey]";
} else if (item.getItemId() == R.id.highestRated) {
FILM_REQUEST_URL = "http://api.themoviedb.org/3/movie/top_rated?api_key=[MyNetworkKey]";
}
// Clear the adapter of previous film data
mAdapter.clear();
// Get the revised film list
List<Film> films = QueryUtils.fetchFilmData(FILM_REQUEST_URL);
// Populate the adapters data set
if (films != null && !films.isEmpty()) {
mAdapter.addAll(films);
}
return super.onOptionsItemSelected(item);
}
Logcat 错误: Logcat Error Trace
QueryUtils.java:
公共(public)类 QueryUtils {
private QueryUtils() {
}
/** Tag for log messages */
private static final String LOG_TAG = QueryUtils.class.getSimpleName();
/**
* Query TMDb and return a list of {@link Film} objects
*/
public static List<Film> fetchFilmData(String requestUrl) {
// Create a URL object
URL url = createUrl(requestUrl);
//Call HTTP request to URL and get JSON response
String jsonResponse = null;
try {
jsonResponse = makeHttpRequest(url);
} catch (IOException e) {
Log.e(LOG_TAG, "Problem making the HTTP request ", e);
}
// Extract relevant fields from the JSON response and return the list of films
return extractFeatureFromJson(jsonResponse);
}
/**
* Returns new URL object from the given string URL
*/
private static URL createUrl(String stringUrl) {
URL url = null;
try {
url = new URL(stringUrl);
} catch (MalformedURLException e) {
Log.e(LOG_TAG, "Problem building the URL ", e);
}
return url;
}
/**
* Make HTTP request to the URL and return a String as the response
*/
private static String makeHttpRequest(URL url) throws IOException {
String jsonResponse = "";
// If the URL is null, then return
if (url == null) {
return jsonResponse;
}
HttpURLConnection urlConnection = null;
InputStream inputStream = null;
try {
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setReadTimeout(10000 /* milliseconds */);
urlConnection.setConnectTimeout(15000 /* milliseconds */);
urlConnection.setRequestMethod("GET");
urlConnection.connect();
// If the request was successful (response code 200),
// then read the input stream and parse the response.
if (urlConnection.getResponseCode() == 200) {
inputStream = urlConnection.getInputStream();
jsonResponse = readFromStream(inputStream);
} else {
Log.e(LOG_TAG, "Error response code: " + urlConnection.getResponseCode());
}
} catch (IOException e) {
Log.e(LOG_TAG, "Problem retrieving the movie JSON results ", e);
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (inputStream != null) {
// Closing the input stream could throw an IOException, which is why
// the makeHttpRequest(URL url) method signature specifies than an IOException
// could be thrown
inputStream.close();
}
}
return jsonResponse;
}
/**
* Convert the {@link InputStream} into a String that contains JSON
* response from the server
*/
private static String readFromStream(InputStream inputStream) throws IOException {
StringBuilder output = new StringBuilder();
if (inputStream != null) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
BufferedReader reader = new BufferedReader(inputStreamReader);
String line = reader.readLine();
while (line != null) {
output.append(line);
line = reader.readLine();
}
}
return output.toString();
}
/**
* Return a list of {@link Film} objects that has been built up from
* parsing the given JSON response
*/
private static List<Film> extractFeatureFromJson(String filmJSON) {
// If the JSON string is empty or null, then return
if (TextUtils.isEmpty(filmJSON)) {
return null;
}
// Create an empty ArrayList that we can start adding films to
List<Film> films = new ArrayList<>();
// Try to parse the JSON response string. If there's a problem with the way the JSON
// is formatted, a JSONException exception object will be thrown
try {
// Create a JSONObject from the JSON response string
JSONObject baseJsonResponse = new JSONObject(filmJSON);
// Extract the JSONArray associated with the key called "results",
// which represents a list of films
JSONArray filmArray = baseJsonResponse.getJSONArray("results");
// For each movie in the movieArray, create an {@link Film} object
for (int i = 0; i < filmArray.length(); i++) {
// Get a single movie at position i within the list of movies
JSONObject currentFilm = filmArray.getJSONObject(i);
// Extract the value for individual keys from JSONObject results
int voteCount = currentFilm.getInt("vote_count");
long voteAverage = currentFilm.getLong("vote_average");
String title = currentFilm.getString("title");
long popularity = currentFilm.getLong("popularity");
String posterUrl = "http://image.tmdb.org/t/p/w185" + currentFilm.getString("poster_path");
String overview = currentFilm.getString("overview");
String releaseDate = currentFilm.getString("release_date");
// Create a new {@link Film} object with the vote count, vote average, title,
// popularity, poster path, overview, and release date from the JSON response
Film film = new Film(voteCount, voteAverage, title, popularity, posterUrl,
overview, releaseDate);
// Add the new {@link Film} to the list of movies
films.add(film);
}
} catch (JSONException e) {
// If an error is thrown when executing any of the above statements in the "try" block,
// catch the exception here, so the app doesn't crash. Print a log message
// with the message from the exception
Log.e("QueryUtils", "Problem parsing the TMDb JSON results", e);
}
// Return the list of films
return films;
}
}
最佳答案
来自:https://developer.android.com/reference/android/os/NetworkOnMainThreadException
NetworkOnMainThreadException:
The exception that is thrown when an application attempts to perform a networking operation on its main thread.
为了避免此异常,您需要在单独的线程上发出 HTTP 请求。实现此目的的一种可能方法是使用 AsyncTask .
Here是一篇 stackoverflow 文章,介绍如何使用 AsyncTask 发出 HTTP GET 请求。
关于java - 在 onOptionsItemSelected 中选择第二个项目会导致应用程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50068441/
对于 onOptionsItemSelected 方法,只有在单击项目时才会调用此方法,对吗?如果在该 Activity 中单击了一个项目,但由于某些奇怪的原因,程序员没有 if 语句来检查该项目的
我有一个可以包含多个 fragment 的 Activity 。每个 fragment 都可以在 ActionBar 中有自己的菜单项。到目前为止这工作正常,每个项目都是可点击的并执行所需的操作。 我
我对这段代码感到困惑,我有 6 个菜单项,每个菜单项我希望它在 Web View 上加载不同的网页,但我看不到我在哪里可以说当选择第 3 项时执行此操作,有人可以帮忙吗? @Override
我的 fragment 上有这个调用 @Override public boolean onOptionsItemSelected(MenuItem item) { Toast
使用 Android Studio,我正在为我的应用程序创建设置(这是我第一次这样做)。我遇到了 onOptionsItemSelected 问题,我不知道如何继续。这是我的 LogCat: FATA
我有一个实现 onCreateOptionsMenu 方法的顶级 TabHost。我希望子 Activity (选项卡内的子 Activity )能够通过 onOptionsItemSelected
如何避免双击我的示例,任何解决方案? @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getI
我对 public boolean onOptionsItemSelected(MenuItem item) 有问题。 我的代码: public boolean onOptionsItemSelect
我的操作栏上有两个按钮,一个注销按钮和一个创建新消息按钮。但是,如果我单击创建新消息按钮(什么都不应该发生),它会让我退出。我的代码设置为它应该做的。有什么建议吗? @Override pub
我是 Android 开发的新手。 在我的 MainActivity.java 文件中,我声明了一个 onOptionsItemSelected(MenuItem menu) 方法,允许用户在当前 M
我遇到过这样一种情况,我需要为一个项目的子菜单实现 onOptionsItemSelected 监听器。菜单 xml 文件如下所示:
我不确定这是否重复,我尝试过的可能的补救措施无效。 (下面会提到) 我目前正在为我正在做的项目使用 Theme.AppCompat.NoActionBar 并且正在使用 android.support
我在 Android 中的一项 Activity 中有一个抽屉导航。我还在同一 Activity 的操作栏中添加了几个操作按钮和一个操作溢出。现在,问题在于处理抽屉导航项目、操作按钮和操作溢出菜单的选
我已经为我的数据库类创建了一个选项菜单。启动选项菜单后,我想通过单击指定按钮进行所需的 Activity 。 但问题是,如果我单击任何选项,我将被定向到 MainMenu.class。任何想法为什么会
我是 Android 的新手,如果我的问题看起来很简单,我很抱歉。我昨晚整晚都在查找它,但找不到解决方案(这让我觉得我可能在我试图实现的目标上存在根本缺陷)。 基本上,我试图从 onOptionsIt
我正在使用我的 fragment 处理返回功能。我使用操作栏作为返回按钮,但函数 onOptionsItemSelected 不起作用(甚至可能未调用该函数) 此代码在我的 FragmentActiv
我的操作栏中有一个菜单项列表。每个项目点击应该触发不同的方法。但是永远不会调用 onOptionsItemSelected。 这是在 MainActivity 中定义 actionbar 的方式: p
我有一个带有两个按钮的 onOptionsItemSelected 方法,我可以通过单击其中一个按钮来更改子项的值。 一个按钮是“完成”,另一个是“进行中”。 我单击完成按钮,它正确地更改了子值,然后
我使用 Sherlock 的操作栏。我正在尝试将其实现到我的应用程序中。但似乎我错过了一些让它发挥作用的东西。请检查我的代码。当我点击操作按钮时,我的应用程序没有做任何事情。下面是我的代码和我的 xm
我目前正在开发一款 Android 应用。我想使用操作栏中的应用程序图标导航到“主页” Activity 。我继续阅读 this所有需要做的就是添加一个 onOptionsItemSelected 并
我是一名优秀的程序员,十分优秀!