在 Android 中搜索时显示进度对话框
我阅读了 stackoverflow 上的所有问题,这些问题可以给我一个提示,但我无法让它工作。
我拥有的:
我有一个名为“wantlist”的活动,它启动我的应用程序。在此活动中,我有一个按钮,可以通过 onSearchRequested() 开始搜索;
我有另一个名为“discogssearch”的活动,它调用互联网上的 XML Api、解析数据并显示搜索结果。
所有这一切都运行良好。
我想要实现的目标:
我想在发出耗时的 api 调用时显示 ProgessDialog。
我尝试过的:
在搜索开始之前,我尝试通过多种方式打开 ProgessDialog 并发现,我必须与主线程异步执行此操作。所以我把耗时的代码放入AsyncTask中并启动它。
发生了什么:
当我输入文本并按回车键时,什么也没有发生(像以前一样),直到结果到达。现在“discogssearch”透视图与结果一起显示,并且进度对话框显示,但此时所有工作都已完成。
我的代码:
wantlist.java
public class wantlist extends Activity implements OnClickListener {
/** Called when the activity is first created. */
ArrayList<Want> wants = new ArrayList<Want>();
@Override
public void onCreate(Bundle savedInstanceState) {
wants.add(new Want("Want1"));
wants.add(new Want("Want2"));
wants.add(new Want("Want3"));
wants.add(new Want("Want4"));
wants.add(new Want("Want5"));
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ListView lv = (ListView) findViewById(R.id.WantList);
ImageButton b = (ImageButton) findViewById(R.id.searchbutton);
b.setOnClickListener(this);
lv.setAdapter(new WantAdapter(this,
R.layout.lplistitem, wants));
lv.setTextFilterEnabled(true);
}
public void onClick(View v) {
onSearchRequested();
}
}
discogssearch.java
public class discogssearch extends Activity implements OnItemClickListener{
/** Called when the activity is first created. */
private static final int PROGRESS_DIALOG = 0;
private static final String LOGTAG = discogssearch.class.getName();
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
Window window = getWindow();
// Eliminates color banding
window.setFormat(PixelFormat.RGBA_8888);
}
private ListView alv = null;
private ListView rlv = null;
private ListView llv = null;
ArrayList<Want> results = new ArrayList<Want>();
View.OnTouchListener gestureListener;
GestureDetector pageFlip;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.searchresults);
Intent intent = getIntent();
String query = intent.getStringExtra(SearchManager.QUERY);
searchDiscogs(query);
}
public void searchDiscogs(String query)
{
query = URLEncoder.encode(query);
alv = (ListView) findViewById(R.id.ArtistList);
rlv = (ListView) findViewById(R.id.ReleaseList);
llv = (ListView) findViewById(R.id.LabelList);
rlv.setOnItemClickListener(this);
rlv.setFastScrollEnabled(true);
rlv.setVerticalFadingEdgeEnabled(true);
results.clear();
AsyncTask<String, Integer, DiscogsXMLHandler> at = new AsyncDiscogsSearch().execute(query);
DiscogsXMLHandler discogsHandler = null;
try {
discogsHandler = at.get();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.d("WICHTIG: ",discogsHandler.getReleaseResults().size() + "");
alv.setAdapter(new WantAdapter(this,
R.layout.lplistitem, discogsHandler.getArtistResults()));
rlv.setAdapter(new WantAdapter(this,
R.layout.lplistitem, discogsHandler.getReleaseResults()));
llv.setAdapter(new WantAdapter(this,
R.layout.lplistitem, discogsHandler.getLabelResults()));
}
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
if(arg0.equals(rlv))
{
String uri = ((Want)rlv.getItemAtPosition(arg2)).getDetailsUri();
Log.d("Itemclick", uri);
Intent viewUri = new Intent("android.intent.action.VIEW", Uri.parse(uri));
viewUri.setClass(this, releasedetails.class);
startActivity(viewUri);
}
}
public Dialog onCreateDialog(int dial)
{
switch(dial) {
case PROGRESS_DIALOG:
Log.d(LOGTAG,"Showing Progress Dialog");
ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Loading...");
return progressDialog;
default:
return null;
}
}
private Animation inFromRightAnimation() {
Animation inFromRight = new TranslateAnimation(
Animation.RELATIVE_TO_PARENT, +1.0f,
Animation.RELATIVE_TO_PARENT, 0.0f,
Animation.RELATIVE_TO_PARENT, 0.0f,
Animation.RELATIVE_TO_PARENT, 0.0f);
inFromRight.setDuration(100);
inFromRight.setInterpolator(new AccelerateInterpolator());
return inFromRight;
}
private Animation outToLeftAnimation() {
Animation outtoLeft = new TranslateAnimation(
Animation.RELATIVE_TO_PARENT, 0.0f,
Animation.RELATIVE_TO_PARENT, -1.0f,
Animation.RELATIVE_TO_PARENT, 0.0f,
Animation.RELATIVE_TO_PARENT, 0.0f);
outtoLeft.setDuration(100);
outtoLeft.setInterpolator(new AccelerateInterpolator());
return outtoLeft;
}
private Animation inFromLeftAnimation() {
Animation inFromLeft = new TranslateAnimation(
Animation.RELATIVE_TO_PARENT, -1.0f,
Animation.RELATIVE_TO_PARENT, 0.0f,
Animation.RELATIVE_TO_PARENT, 0.0f,
Animation.RELATIVE_TO_PARENT, 0.0f);
inFromLeft.setDuration(100);
inFromLeft.setInterpolator(new AccelerateInterpolator());
return inFromLeft;
}
private Animation outToRightAnimation() {
Animation outtoRight = new TranslateAnimation(
Animation.RELATIVE_TO_PARENT, 0.0f,
Animation.RELATIVE_TO_PARENT, +1.0f,
Animation.RELATIVE_TO_PARENT, 0.0f,
Animation.RELATIVE_TO_PARENT, 0.0f);
outtoRight.setDuration(100);
outtoRight.setInterpolator(new AccelerateInterpolator());
return outtoRight;
}
private class AsyncDiscogsSearch extends AsyncTask<String, Integer, DiscogsXMLHandler>{
public static final String APIKEY = "xxxxxxxx";
private final ProgressDialog pg = new ProgressDialog(discogssearch.this);
@Override
protected DiscogsXMLHandler doInBackground(String... params) {
String urlString = "http://www.discogs.com/search?type=all&q="+params[0]+"&f=xml&api_key="+APIKEY ;
//Retrieve XML-Data as InputStream
InputStream instream = GZipStreamHelper.getStream(urlString);
//Parse XML-Data
DiscogsXMLHandler discogsHandler = new DiscogsXMLHandler();
XMLParsingHelper.getInstance().parseAndHandle(instream, discogsHandler);
return discogsHandler;
}
@Override
protected void onPostExecute(DiscogsXMLHandler result) {
// TODO Auto-generated method stub
pg.dismiss();
}
@Override
protected void onPreExecute() {
pg.show();
}
}
}
感谢您的任何建议!
I read all Questions on stackoverflow that could give me a hint with this but i can't get this to work.
What i have:
I've got an activy called "wantlist" which starts witch my app. On this activity i have a button which starts a search via onSearchRequested();
I have another activity called "discogssearch" which makes a call to an XML Api on the internet, parses the data and displays the search results.
All of this is working fine.
What i want to achieve:
I want to display a ProgessDialog while the time consuming api call is beeing issued.
What i tried:
I tried opening a ProgessDialog on many ways before the search starts and found out, that i have to do this asynchronous to the main thread. So i put the time consuming code into an AsyncTask and started it.
What happens:
When i entered a text and hit enter nothings happening (as before) until the results arrive. Now the "discogssearch" perspective is beeing displayed with the results and the ProgressDialog shows up but a this point all the work is done already.
My Code:
wantlist.java
public class wantlist extends Activity implements OnClickListener {
/** Called when the activity is first created. */
ArrayList<Want> wants = new ArrayList<Want>();
@Override
public void onCreate(Bundle savedInstanceState) {
wants.add(new Want("Want1"));
wants.add(new Want("Want2"));
wants.add(new Want("Want3"));
wants.add(new Want("Want4"));
wants.add(new Want("Want5"));
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ListView lv = (ListView) findViewById(R.id.WantList);
ImageButton b = (ImageButton) findViewById(R.id.searchbutton);
b.setOnClickListener(this);
lv.setAdapter(new WantAdapter(this,
R.layout.lplistitem, wants));
lv.setTextFilterEnabled(true);
}
public void onClick(View v) {
onSearchRequested();
}
}
discogssearch.java
public class discogssearch extends Activity implements OnItemClickListener{
/** Called when the activity is first created. */
private static final int PROGRESS_DIALOG = 0;
private static final String LOGTAG = discogssearch.class.getName();
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
Window window = getWindow();
// Eliminates color banding
window.setFormat(PixelFormat.RGBA_8888);
}
private ListView alv = null;
private ListView rlv = null;
private ListView llv = null;
ArrayList<Want> results = new ArrayList<Want>();
View.OnTouchListener gestureListener;
GestureDetector pageFlip;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.searchresults);
Intent intent = getIntent();
String query = intent.getStringExtra(SearchManager.QUERY);
searchDiscogs(query);
}
public void searchDiscogs(String query)
{
query = URLEncoder.encode(query);
alv = (ListView) findViewById(R.id.ArtistList);
rlv = (ListView) findViewById(R.id.ReleaseList);
llv = (ListView) findViewById(R.id.LabelList);
rlv.setOnItemClickListener(this);
rlv.setFastScrollEnabled(true);
rlv.setVerticalFadingEdgeEnabled(true);
results.clear();
AsyncTask<String, Integer, DiscogsXMLHandler> at = new AsyncDiscogsSearch().execute(query);
DiscogsXMLHandler discogsHandler = null;
try {
discogsHandler = at.get();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.d("WICHTIG: ",discogsHandler.getReleaseResults().size() + "");
alv.setAdapter(new WantAdapter(this,
R.layout.lplistitem, discogsHandler.getArtistResults()));
rlv.setAdapter(new WantAdapter(this,
R.layout.lplistitem, discogsHandler.getReleaseResults()));
llv.setAdapter(new WantAdapter(this,
R.layout.lplistitem, discogsHandler.getLabelResults()));
}
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
if(arg0.equals(rlv))
{
String uri = ((Want)rlv.getItemAtPosition(arg2)).getDetailsUri();
Log.d("Itemclick", uri);
Intent viewUri = new Intent("android.intent.action.VIEW", Uri.parse(uri));
viewUri.setClass(this, releasedetails.class);
startActivity(viewUri);
}
}
public Dialog onCreateDialog(int dial)
{
switch(dial) {
case PROGRESS_DIALOG:
Log.d(LOGTAG,"Showing Progress Dialog");
ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Loading...");
return progressDialog;
default:
return null;
}
}
private Animation inFromRightAnimation() {
Animation inFromRight = new TranslateAnimation(
Animation.RELATIVE_TO_PARENT, +1.0f,
Animation.RELATIVE_TO_PARENT, 0.0f,
Animation.RELATIVE_TO_PARENT, 0.0f,
Animation.RELATIVE_TO_PARENT, 0.0f);
inFromRight.setDuration(100);
inFromRight.setInterpolator(new AccelerateInterpolator());
return inFromRight;
}
private Animation outToLeftAnimation() {
Animation outtoLeft = new TranslateAnimation(
Animation.RELATIVE_TO_PARENT, 0.0f,
Animation.RELATIVE_TO_PARENT, -1.0f,
Animation.RELATIVE_TO_PARENT, 0.0f,
Animation.RELATIVE_TO_PARENT, 0.0f);
outtoLeft.setDuration(100);
outtoLeft.setInterpolator(new AccelerateInterpolator());
return outtoLeft;
}
private Animation inFromLeftAnimation() {
Animation inFromLeft = new TranslateAnimation(
Animation.RELATIVE_TO_PARENT, -1.0f,
Animation.RELATIVE_TO_PARENT, 0.0f,
Animation.RELATIVE_TO_PARENT, 0.0f,
Animation.RELATIVE_TO_PARENT, 0.0f);
inFromLeft.setDuration(100);
inFromLeft.setInterpolator(new AccelerateInterpolator());
return inFromLeft;
}
private Animation outToRightAnimation() {
Animation outtoRight = new TranslateAnimation(
Animation.RELATIVE_TO_PARENT, 0.0f,
Animation.RELATIVE_TO_PARENT, +1.0f,
Animation.RELATIVE_TO_PARENT, 0.0f,
Animation.RELATIVE_TO_PARENT, 0.0f);
outtoRight.setDuration(100);
outtoRight.setInterpolator(new AccelerateInterpolator());
return outtoRight;
}
private class AsyncDiscogsSearch extends AsyncTask<String, Integer, DiscogsXMLHandler>{
public static final String APIKEY = "xxxxxxxx";
private final ProgressDialog pg = new ProgressDialog(discogssearch.this);
@Override
protected DiscogsXMLHandler doInBackground(String... params) {
String urlString = "http://www.discogs.com/search?type=all&q="+params[0]+"&f=xml&api_key="+APIKEY ;
//Retrieve XML-Data as InputStream
InputStream instream = GZipStreamHelper.getStream(urlString);
//Parse XML-Data
DiscogsXMLHandler discogsHandler = new DiscogsXMLHandler();
XMLParsingHelper.getInstance().parseAndHandle(instream, discogsHandler);
return discogsHandler;
}
@Override
protected void onPostExecute(DiscogsXMLHandler result) {
// TODO Auto-generated method stub
pg.dismiss();
}
@Override
protected void onPreExecute() {
pg.show();
}
}
}
Thanks for any suggestions!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
据我了解,您的行
discogsHandler = at.get();
会阻塞您的 UI 线程。 onPreExecute 被执行,但这只会将进度对话框放入主线程的消息循环中。但是,实际打开和处理对话框的代码是在从searchDiscogs()
返回后执行的。解决方案是将查询结果的处理放入
AsyncTask
中 < code>onPostExecute,或从那里调用结果处理方法。As I understand it, your line
discogsHandler = at.get();
blocks your UI thread. onPreExecute is executed, but this only puts the progress dialog into the main thread's message loop. However, the code that actually opens and handles the dialog is executed after returning fromsearchDiscogs()
A solution would be to put your handling of the query's result into the
AsyncTask
sonPostExecute
, or call result handling method from there.我认为 user634618 是正确的。
AsyncTask#get()
指出:
(强调是后加的)。因此,UI 线程只是停留在对
get
的调用处,并且您失去了执行AsyncTask
的意义。由于 UI 线程被阻塞,因此您显示进度对话框的请求不会被执行。正如 user634618 所建议的,您可以在 onPostExecute 中处理搜索结果,这将释放 UI 线程并允许显示进度对话框。
I think user634618 is correct. The documentation for
AsyncTask#get()
states:(Emphasis added). So the UI thread just sits at the call to
get
and you lose the point of performing anAsyncTask
. Since the UI thread is blocked, your request to display a progress dialog is not executed.As user634618 suggests, you can handle the result of the search in
onPostExecute
, which will free up the UI thread and allow your progress dialog to display.