无法使用AsynTask直接从URL读取

时间:2018-04-15 12:37:52

标签: java android android-studio

我正在尝试开发一个从URL读取笑话的应用程序。我使用AsyncTask从URL读取,然后将字符串放到textView。但我无法弄清楚它为什么不起作用。 这是我的代码:

public class MainActivity extends AppCompatActivity {
private Button oneJokeBtn, threeJokesBtn;
private final static String ERROR_TAG = "Download Error";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    // Capturing our buttons from the view
    oneJokeBtn = findViewById(R.id.joke_1);
    threeJokesBtn = findViewById(R.id.joke_3);
    // Register the onClick listener
    oneJokeBtn.setOnClickListener(buttonHandler);
    threeJokesBtn.setOnClickListener(buttonHandler);
    // Declaring the Spinner
    Spinner spinner = findViewById(R.id.spinner);
    // Create an ArrayAdapter using the string array and a default spinner layout
    ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
            R.array.length_array, android.R.layout.simple_spinner_item);
    // Specify the layout to use when the list of choices appears
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    // Apply the adapter to the spinner
    spinner.setAdapter(adapter);
    // Spinner onItemSelector implemented in the OnCreate Method
    spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            switch (position){
                case 0:
                    Toast.makeText(parent.getContext(), R.string.short_toast, Toast.LENGTH_SHORT).show();
                    break;
                case 1:
                    Toast.makeText(parent.getContext(), R.string.medium_toast, Toast.LENGTH_SHORT).show();
                    break;
                case 2:
                    Toast.makeText(parent.getContext(), R.string.long_toast, Toast.LENGTH_SHORT).show();
                    break;
            }
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {

        }
    });
}
/** AsyncTask that reads one joke directly from the URL and adds it to the textView */
private class Download1JokeAsyncTask extends AsyncTask <Void, Void, String> {
    private ProgressDialog progressDialog;
    private String mResponse = "";

    @Override
    protected void onPreExecute() {
        progressDialog = new ProgressDialog(MainActivity.this);
        progressDialog.setMessage(getString(R.string.progress_msg));
        progressDialog.setIndeterminate(true);
        progressDialog.show();
    }

    @Override
    protected String doInBackground(Void... voids) {
        String joke = null;
        try {
            // Open a connection to the web service
            URL url = new URL( "http://www-staff.it.uts.edu.au/~rheise/sarcastic.cgi" );
            URLConnection conn = url.openConnection();
            // Obtain the input stream
            BufferedReader in = new BufferedReader( new InputStreamReader(conn.getInputStream()));
            // The joke is a one liner, so just read one line.
            joke = in.readLine();
            // Close the connection
            in.close();
        } catch (MalformedURLException e) {
            e.printStackTrace();
            Log.e(ERROR_TAG, "Exception: ", e);
            mResponse = getString(R.string.fail_msg);
            } catch (IOException e) {
            e.printStackTrace();
            Log.e(ERROR_TAG, "Exception: ", e);
            mResponse = getString(R.string.fail_msg);
        }
        return joke;
    }

    @Override
    protected void onPostExecute(String joke) {
        TextView tv = findViewById(R.id.tv_joke);
        if (joke == null) {
            tv.setText(R.string.fail_msg);
        }
        else {
            tv.setText(joke);
        }
        if (progressDialog.isShowing()) {
            progressDialog.dismiss();
        }
    }

}

/** AsyncTask that reads three jokes directly from the URL and adds it to the textView */
private class Download3JokeAsyncTask extends AsyncTask<Void, Integer, String[]> {
    private ProgressDialog mProgressDialog;

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        mProgressDialog = new ProgressDialog(MainActivity.this);
        mProgressDialog.setProgress(0);
        mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        mProgressDialog.setIndeterminate(false);
        mProgressDialog.setMax(100);
        mProgressDialog.setCancelable(true);
        mProgressDialog.setMessage(getString(R.string.three_jokes_btn));
        mProgressDialog.show();
    }

    @Override
    protected String[] doInBackground(Void... voids) {
        int count = 2;
        for (int i = 0; i < 2; i++){
            try {
                URL url = new URL("http://www.oracle.com/");
                URLConnection conn = url.openConnection();
                // Obtain the input stream
                BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                // The joke is a one liner, so just read one line.
                String joke;
                while ((joke = in.readLine()) != null) {
                    System.out.println(joke);
                }
                // Close the connection
                in.close();
            } catch (MalformedURLException e) {
                e.printStackTrace();
                Log.e(ERROR_TAG, "Exception: ", e);
            } catch (IOException e) {
                e.printStackTrace();
                Log.e(ERROR_TAG, "Exception: ", e);
            }
            publishProgress((int) ((i / (float) count) * 100));
        }
        return null;
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        setProgress(0);

    }

    @Override
    protected void onPostExecute(String[] strings) {
        super.onPostExecute(strings);
    }
}
/** onClickListener that gets the id of the button pressed and download jokes accordingly */
OnClickListener buttonHandler = new OnClickListener() {
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.joke_1:
                new Download1JokeAsyncTask().execute();
                break;
            case R.id.joke_3:
                new Download3JokeAsyncTask().execute();
                break;
        }
    }
};

AsyncTask被称为Download1JokeAsyncTask,它应该从URL读取然后将其放入文本视图中。如果笑话(存储笑话的字符串)为空,我会在文本视图中显示一条错误消息。 并且文本视图始终表示无法下载消息。 请帮忙。

1 个答案:

答案 0 :(得分:0)

我去了your joke page并检查了源代码(在Firefox中),我发现了这个:

<html>
  <head>
    <link rel="alternate stylesheet" type="text/css" href="resource://content-accessible/plaintext.css" title="Wrap Long Lines">
  </head>
  <body>
   <pre>I'm really good at stuff until people watch me do that stuff.</pre>
  </body>
</html>

因此,您可以将整个输出保存为String,然后使用:

string.substring(string.indexOf("<pre>"), string.indexOf("</pre>");
string.substring(4);

基本上,您只下载页面的第一行,即内容声明。

相反,您需要下载第六行并删除pre标记。

祝你好运!