尝试直接从网址

时间:2018-04-14 09:05:00

标签: java android android-asynctask

我正在尝试设计一个直接从URL读取笑话的应用程序,但出于某种原因,当我按下按钮启动该过程时,我无法弄清楚它是否会崩溃。

我使用两个按钮,一个读一个笑话,另一个读三个笑话。 单击第一个按钮时,它将调用AsyncTask,从URL中提取读数并显示进度条,直到笑话下载。 第二个按钮执行相同但下载3个笑话而不是一个。 这是mainActivity类。

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

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // Capturing the TextView from our View
        mJokeTv = findViewById(R.id.tv_joke);
        // 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;

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

    @Override
    protected String doInBackground(Void... voids) {
        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);
        }
        return null;
    }

    @Override
    protected void onPostExecute(String joke) {
        mJokeTv.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(getApplicationContext());
        mProgressDialog.setProgress(0);
        mProgressDialog.setIndeterminate(false);
        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) {
        super.onProgressUpdate(values);

    }

    @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;
        }
    }
};

这里是LogCat的日志:

--------- beginning of crash

04-14 18:57:10.670 17411-17411/com.mad.exercise4 E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.mad.exercise4, PID: 17411
    android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?
        at android.view.ViewRootImpl.setView(ViewRootImpl.java:765)
        at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:356)
        at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:93)
        at android.app.Dialog.show(Dialog.java:330)
        at com.mad.exercise4.MainActivity$Download3JokeAsyncTask.onPreExecute(MainActivity.java:136)
        at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:648)
        at android.os.AsyncTask.execute(AsyncTask.java:595)
        at com.mad.exercise4.MainActivity$2.onClick(MainActivity.java:187)
        at android.view.View.performClick(View.java:6294)
        at android.view.View$PerformClick.run(View.java:24770)
        at android.os.Handler.handleCallback(Handler.java:790)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6494)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
04-14 18:57:10.721 17411-17416/com.mad.exercise4 I/zygote: Do full code cache collection, code=92KB, data=56KB
    After code cache collection, code=90KB, data=44KB


----------

我没有填充第二个AsyncTask代码,因为它也会导致相同的错误。

请帮助:)。

2 个答案:

答案 0 :(得分:1)

尝试使用

progressDialog = new ProgressDialog(MainActivity.this); 

而不是

progressDialog = new ProgressDialog(getApplicationContext());

答案 1 :(得分:0)

您需要替换

/search/?name=moviename

mProgressDialog = new ProgressDialog(getApplicationContext());

参考:

Android 1.6: "android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application"