放入 Android Activity 时没有来自 HTTP GET 代码的响应
No response from HTTP GET code when put in Android Activity
我正在尝试编写一个涉及 activity 的应用程序,该应用程序向网页发送 GET 请求,获取代码作为响应,然后将其解析为一个特定的字符串(获胜者的姓名)。当我 运行 它作为我的终端上的独立 Java 代码时,这工作得很好。将其放入 Android activity 虽然没有产生任何结果:既不成功也不错误。
下面是 MainActivity 的代码:
package com.projects.appbrewers.swaghrwtracker;
package com.example.myprojects.myapp;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class MainActivity extends AppCompatActivity {
private final String USER_AGENT = "Mozilla/5.0";
String url = "<some URL here>";
String currentWinnerName = "";
TextView currentWinnerLabel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
currentWinnerLabel = (TextView)findViewById(R.id.currentWinnerLabel);
currentWinnerLabel.setText("Finding...");
try
{
checkCurrentWinner();
}
catch (Exception e)
{
//print e.getMessage() to log
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
//HTTP GET Request to Swagbucks HRW iframe page
public void checkCurrentWinner() throws Exception
{
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
// optional default is GET
con.setRequestMethod("GET");
//add request header
con.setRequestProperty("User-Agent", USER_AGENT);
int responseCode = con.getResponseCode();
if(responseCode == 200)
{
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null)
{
response.append(inputLine);
}
in.close();
// strip out your required data with a regex
Pattern pattern = Pattern.compile(".*<div id=\"randomWinnerName\">([a-z0-9]*)</div>.*");
Matcher matcher = pattern.matcher(response.toString());
if (matcher.find())
{
currentWinnerName = matcher.group(1);
currentWinnerLabel.setText(currentWinnerName);
}
else
currentWinnerLabel.setText("Not Found!");
}
else
currentWinnerLabel.setText("ERROR!");
}
}
您需要 运行 在单独的线程中而不是在 UI 线程中。使用AsyncTask执行checkCurrentWinner()
private class CheckCurrentWinner extends AsyncTask<Integer, Void, String> {
public CheckCurrentWinner(String url) {
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected String doInBackground(Integer... params) {
try {
checkCurrentWinner();
} catch (Exception e) {
}
return null;
}
@Override
protected void onPostExecute(String result) {
}
在 'onPostExecute()' 你可以改变 currentWinnerLabel
您可以使用新的 CheckCurrentWinner().execute()
调用此 class
我确定这里会抛出NetworkOnMainThread Exception,并不是像你说的没有出错。所以,你只需要像这样把它放在一个单独的线程中:
new Thread(new Runnable()
{
@Override
public void run()
{
try
{
checkCurrentWinner();
}
catch (Exception e)
{
//print e.getMessage() to log
}
}
}).start();
这里有两种选择:
1.使用AsyncTask
执行HTTP GET操作
private class CheckUsernameFromUrlTask extends AsyncTask<URL, Integer, String> {
protected String doInBackground(URL... urlToGetTheUsername) {
String usernameFromHttpGetMethod = null;
// code to make (similar to your checkCurrentWinner method)
// 1. HTTP GET request
// 2. Extract username (incl. error handling)
return usernameFromHttpGetMethod;
}
protected void onProgressUpdate(Integer... progress) {
// ignore for now, unless you want to show the progress blocking UI
}
protected void onPostExecute(String result) {
// back in the UI thread. Perform all view operations
// Handle exceptions by saving the exception thrown in
// doInBackground method as an instance variable of this class or
// changing the return object to be a custom object containing
// username and exception.
String labelText = result == null ? "Not Found!" : result;
currentWinnerLabel.setText(labelText );
}
}
然后使用AsyncTask
@Override
protected void onCreate(Bundle savedInstanceState) {
// ...
new CheckUsernameFromUrlTask ().execute(url1, url2, url3);
}
- 使用retrofit 库。该库使用回调对象通过后台线程异步获取请求,因此您不必为 AsyncTask 编写代码。有关示例,请参阅改造文档。
我正在尝试编写一个涉及 activity 的应用程序,该应用程序向网页发送 GET 请求,获取代码作为响应,然后将其解析为一个特定的字符串(获胜者的姓名)。当我 运行 它作为我的终端上的独立 Java 代码时,这工作得很好。将其放入 Android activity 虽然没有产生任何结果:既不成功也不错误。
下面是 MainActivity 的代码:
package com.projects.appbrewers.swaghrwtracker;
package com.example.myprojects.myapp;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class MainActivity extends AppCompatActivity {
private final String USER_AGENT = "Mozilla/5.0";
String url = "<some URL here>";
String currentWinnerName = "";
TextView currentWinnerLabel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
currentWinnerLabel = (TextView)findViewById(R.id.currentWinnerLabel);
currentWinnerLabel.setText("Finding...");
try
{
checkCurrentWinner();
}
catch (Exception e)
{
//print e.getMessage() to log
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
//HTTP GET Request to Swagbucks HRW iframe page
public void checkCurrentWinner() throws Exception
{
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
// optional default is GET
con.setRequestMethod("GET");
//add request header
con.setRequestProperty("User-Agent", USER_AGENT);
int responseCode = con.getResponseCode();
if(responseCode == 200)
{
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null)
{
response.append(inputLine);
}
in.close();
// strip out your required data with a regex
Pattern pattern = Pattern.compile(".*<div id=\"randomWinnerName\">([a-z0-9]*)</div>.*");
Matcher matcher = pattern.matcher(response.toString());
if (matcher.find())
{
currentWinnerName = matcher.group(1);
currentWinnerLabel.setText(currentWinnerName);
}
else
currentWinnerLabel.setText("Not Found!");
}
else
currentWinnerLabel.setText("ERROR!");
}
}
您需要 运行 在单独的线程中而不是在 UI 线程中。使用AsyncTask执行checkCurrentWinner()
private class CheckCurrentWinner extends AsyncTask<Integer, Void, String> {
public CheckCurrentWinner(String url) {
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected String doInBackground(Integer... params) {
try {
checkCurrentWinner();
} catch (Exception e) {
}
return null;
}
@Override
protected void onPostExecute(String result) {
}
在 'onPostExecute()' 你可以改变 currentWinnerLabel
您可以使用新的 CheckCurrentWinner().execute()
调用此 class我确定这里会抛出NetworkOnMainThread Exception,并不是像你说的没有出错。所以,你只需要像这样把它放在一个单独的线程中:
new Thread(new Runnable()
{
@Override
public void run()
{
try
{
checkCurrentWinner();
}
catch (Exception e)
{
//print e.getMessage() to log
}
}
}).start();
这里有两种选择:
1.使用AsyncTask
执行HTTP GET操作
private class CheckUsernameFromUrlTask extends AsyncTask<URL, Integer, String> {
protected String doInBackground(URL... urlToGetTheUsername) {
String usernameFromHttpGetMethod = null;
// code to make (similar to your checkCurrentWinner method)
// 1. HTTP GET request
// 2. Extract username (incl. error handling)
return usernameFromHttpGetMethod;
}
protected void onProgressUpdate(Integer... progress) {
// ignore for now, unless you want to show the progress blocking UI
}
protected void onPostExecute(String result) {
// back in the UI thread. Perform all view operations
// Handle exceptions by saving the exception thrown in
// doInBackground method as an instance variable of this class or
// changing the return object to be a custom object containing
// username and exception.
String labelText = result == null ? "Not Found!" : result;
currentWinnerLabel.setText(labelText );
}
}
然后使用AsyncTask
@Override
protected void onCreate(Bundle savedInstanceState) {
// ...
new CheckUsernameFromUrlTask ().execute(url1, url2, url3);
}
- 使用retrofit 库。该库使用回调对象通过后台线程异步获取请求,因此您不必为 AsyncTask 编写代码。有关示例,请参阅改造文档。