美好的一天。 我正在编写我的第一个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)
答案 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();
}
}