停止流程(Android)

时间:2016-09-05 11:30:09

标签: java android android-asynctask

美好的一天。 我正在编写我的第一个Android应用程序,所以请不要踢。 问题是:在按下按钮时,主流不会停止,并且listview不会根据新的用户请求进行更新。我花了近7个小时,已经尝试了所有给谷歌,但它永远不会工作。 任何帮助我都会非常高兴。 (我对代码有任何评论 - 也非常感激)。

代码:

public class MainActivity extends Activity {

    public ArrayList<String> infoList = new ArrayList<>();
    public ArrayList<String> linkList = new ArrayList<>();
    public ArrayAdapter infoAdapter;
    public ListView lv;
    public ProgressBar progressBar;
    public String userRequest;
    EditText eText;
    Button btn;
    NewThread thread;


    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        eText = (EditText) findViewById(R.id.editText1);
        btn = (Button) findViewById(R.id.button);
        lv = (ListView) findViewById(R.id.listView1);
        progressBar = (ProgressBar) findViewById(R.id.progressBar);
        progressBar.setVisibility(ProgressBar.INVISIBLE);
        infoAdapter = new ArrayAdapter<>(MainActivity.this, R.layout.list_item, R.id.song_name, infoList);

        btn.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                thread.stopIt();
                userRequest = eText.getText().toString();
                infoList.clear();
                linkList.clear();
                infoAdapter.notifyDataSetChanged();//*
                thread = new NewThread();
                thread.execute();
                progressBar.setVisibility(ProgressBar.VISIBLE);
            }
        });

        lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                final String downloadLink = linkList.get(position);

                AlertDialog.Builder alertDialog = new AlertDialog.Builder(MainActivity.this);
                alertDialog.setTitle("Downloading...");

                alertDialog.setMessage("Download " + infoList.get(position) + " ?");
                alertDialog.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(downloadLink));
                        startActivity(myIntent);
                    }
                });

                alertDialog.setNegativeButton("No", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.cancel();
                    }
                });
                alertDialog.show();
            }
        });

    }


    public class NewThread extends AsyncTask<String, Integer, String> {

        @Override
        protected String doInBackground(String... arg) {


            try {
                String url = String.format("http://zaycev.net/search.html?query_search=%s",
                        URLEncoder.encode(userRequest, "UTF-8"));
                String useragent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " +
                        "AppleWebKit/537.36 (KHTML, like Gecko) " +
                        "Chrome/52.0.2743.116 Safari/537.36";

                Elements nextPage;
                int number = 0;

                    do {
                        Document doc = Jsoup.connect(url).userAgent(useragent).timeout(5000).get();
                        nextPage = doc.select("[class$=pager__item_last]");
                        Elements resultOfSearch = doc.getElementsByClass("search-page__tracks");
                        Elements elements = resultOfSearch.select("div[data-dkey]");


                        for (Element element : elements) {
                            String artName = element.select(".musicset-track__artist").text();
                            String trackName = element.select(".musicset-track__track-name").text();
                            String trackDur = element.select(".musicset-track__duration").text();

                            Document link = Jsoup
                                    .connect(element.select(".musicset-track__download-link")
                                            .attr("abs:href"))
                                    .userAgent(useragent)
                                    .timeout(5000)
                                    .get();

                            String trackLink = link.select("#audiotrack-download-link").attr("abs:href");

                            infoList.add(artName + " - " + trackName + ": " + trackDur);
                            linkList.add(trackLink);
                            number++;
                            publishProgress();

                        }
                        url = nextPage.attr("abs:href");


                    } while (nextPage.hasAttr("href") && number <= 200);

            } catch (IOException e) {
                e.printStackTrace();

            }
            return null;
        }


        @Override
        protected void onProgressUpdate(Integer... values) {

            lv.setScrollContainer(false);
            Parcelable state = lv.onSaveInstanceState();
            infoAdapter.notifyDataSetChanged(); //*
            lv.setAdapter(infoAdapter);
            lv.onRestoreInstanceState(state);
        }

        @Override
        protected void onPostExecute(String result) {
            progressBar.setVisibility(ProgressBar.INVISIBLE);
        }

        public void stopIt() {
            if (thread == null) {
                return;
            }
            thread.cancel(false);
        }
    }
}

UPD:

我已经通过添加&#34; if(!isCancelled())&#34;更新了doInBackground中的代码,现在我有了这样的logcat:

  

09-05 09:25:05.329 11037-11037 / ru.startandroid.webparser E / InputEventReceiver:异常调度输入事件。   09-05 09:25:05.330 11037-11037 / ru.startandroid.webparser E / MessageQueue-JNI:MessageQueue回调中的异常:handleReceiveCallback   09-05 09:25:05.331 11037-11037 / ru.startandroid.webparser E / MessageQueue-JNI:java.lang.IllegalStateException:适配器的内容已更改但ListView未收到通知。确保不从后台线程修改适配器的内容,而只是从UI线程修改。确保适配器在其内容更改时调用notifyDataSetChanged()。 [在ListView(2131427413,类android.widget.ListView)中使用Adapter(类android.widget.ArrayAdapter)]                                                                                    在android.widget.ListView.layoutChildren(ListView.java:1562)                                                                                    在android.widget.AbsListView.onTouchModeChanged(AbsListView.java:3545)                                                                                    在android.view.ViewTreeObserver.dispatchOnTouchModeChanged(ViewTreeObserver.java:879)                                                                                    在android.view.ViewRootImpl.ensureTouchModeLocally(ViewRootImpl.java:3340)                                                                                    在android.view.ViewRootImpl.ensureTouchMode(ViewRootImpl.java:3324)                                                                                    在android.view.ViewRootImpl $ EarlyPostImeInputStage.processPointerEvent(ViewRootImpl.java:3823)                                                                                    在android.view.ViewRootImpl $ EarlyPostImeInputStage.onProcess(ViewRootImpl.java:3791)                                                                                    在android.view.ViewRootImpl $ InputStage.deliver(ViewRootImpl.java:3449)                                                                                    在android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5701)                                                                                    在android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5675)                                                                                    在android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5646)                                                                                    在android.view.ViewRootImpl $ WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:5791)                                                                                    在android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)                                                                                    在android.os.MessageQueue.nativePollOnce(本机方法)                                                                                    在android.os.MessageQueue.next(MessageQueue.java:143)                                                                                    在android.os.Looper.loop(Looper.java:122)                                                                                    在android.app.ActivityThread.main(ActivityThread.java:5221)                                                                                    at java.lang.reflect.Method.invoke(Native Method)                                                                                    在java.lang.reflect.Method.invoke(Method.java:372)                                                                                    在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:899)                                                                                    在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

1 个答案:

答案 0 :(得分:0)

在这里你可以遇到问题。不要改变/更改适配器从其他线程使用的元素列表。这可能会导致OutOfBounds崩溃或Race Conditions。您可以将解析后的字符串传递给onProgressUpdate(String... parsed),如下所示:

public class NewThread extends AsyncTask<Void, String, Void> {
    protected Void doInBackground(Void... urls) {
        ....
        final String title = artName + " - " + trackName + ": " + trackDur;
        publishProgress(title, link);
    }

    protected void onProgressUpdate(String... parsed) {
         //happens on UI thread so shouldn't cause problems
         infoList.add(parsed[0]);
         linkList.add(parsed[1]);
         infoAdapter.notifyDataSetChanged();
    }
}