简体   繁体   English

尝试直接从URL读取时,我的应用程序崩溃

[英]My application crashes when trying to read directly from URL

I am trying to design an app that reads jokes directly from a URL, but for some reason that I can't figure out it crashes when I press the button to initiate the process. 我正在尝试设计一个直接从URL读取笑话的应用程序,但是由于某些原因,当我按下按钮启动该过程时,我不知道它崩溃了。

I am using two buttons, One to read one joke and another to read three jokes. 我正在使用两个按钮,一个用来阅读一个笑话,另一个用来阅读三个笑话。 When the first button is clicked,it will call an AsyncTask that Intiates the reading from the URL and shows a progress bar until the joke downloads. 单击第一个按钮时,它将调用AsyncTask,该AsyncTask从URL读取读数并显示进度条,直到下载笑话为止。 The second button does the same but downloads 3 jokes instead of one. 第二个按钮执行相同操作,但下载3个笑话而不是1个笑话。 Here is the mainActivity Class. 这是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;
        }
    }
};

Here the log of the LogCat: 这里是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


----------

I haven't populated the second AsyncTask code because it also results in same error. 我没有填充第二个AsyncTask代码,因为它也会导致相同的错误。

Please Help :). 请帮忙 :)。

Try to use 尝试使用

progressDialog = new ProgressDialog(MainActivity.this); 

instead of 代替

progressDialog = new ProgressDialog(getApplicationContext());

You need to replace 您需要更换

mProgressDialog = new ProgressDialog(getApplicationContext());

with

mProgressDialog = new ProgressDialog(this);

Reference: 参考:

Android 1.6: "android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application" Android 1.6:“ android.view.WindowManager $ BadTokenException:无法添加窗口-令牌null不适用于应用程序”

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM