放入 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);
}
  1. 使用retrofit 库。该库使用回调对象通过后台线程异步获取请求,因此您不必为 AsyncTask 编写代码。有关示例,请参阅改造文档。