我正在使用线程将图像设置为背景,在此线程中我有一个对话框。对话框开始,应该在设置壁纸时关闭。这是到目前为止的代码
setWallbtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
final ProgressDialog myPd_ring=ProgressDialog.show(SingleWall.this, "Setting wallpaper", "", true);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
WallpaperManager wallManager = WallpaperManager.getInstance(getApplicationContext());
try {
image = BitmapFactory.decodeStream(url.openConnection().getInputStream());
wallManager.setBitmap(image);
Toast.makeText(SingleWall.this, "Wallpaper Set Successfully!!", Toast.LENGTH_SHORT).show();
myPd_ring.dismiss();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Toast.makeText(SingleWall.this, "Setting WallPaper Failed!!", Toast.LENGTH_SHORT).show();
myPd_ring.dismiss();
}
}
}, 4000);
}
});
因此,点击一个按钮启动线程,4秒钟后,对话框应显示进度图标。但这不正确!设置背景的时间可能多于或少于4秒!所以4000
应该根据时间来计算,将图像设置为壁纸。有可能吗?
PS。我不能使用AsyncTask,因为我得到了很多NullPointerExceptions
答案 0 :(得分:1)
请注意,您没有在问题中使用单独的Thread代码,而是在主UI线程上运行Runnable
。
如果您查看the documentation,建议您使用AsyncTask
解码位图,这也是实现所需结果的最佳方式,其中ProgressDialog只有在过程完成后才会被解雇,这可能会花费不可预测的时间。
您只需将代码放在正确的位置,并通过传递的varargs
为其提供所需内容。
以下是启动AsyncTask
:
setWallbtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new LoadImage().execute(url);
}
});
然后,将AsyncTask
创建为SingleWall
活动的子类。
将网络代码放在doInBackground()
中,它将下载并解码位图,然后将与UI相关的代码放在onPostExecute()
中,该代码在UI线程上运行。
请注意,您也可以使用WeakReference
WallpaperManager
实例,如上面的链接所示,但我会在此处保持简单,只需直接访问wallManager
,如果AsyncTask
是您的活动的子类,则可以执行此操作。
class LoadImage extends AsyncTask<URL, Void, Bitmap> {
ProgressDialog myPd_ring;
@Override
protected void onPreExecute() {
//Start Progress Dialog here
myPd_ring = ProgressDialog.show(SingleWall.this, "Setting wallpaper", "", true);
}
//Runs in a background Thread
@Override
protected Bitmap doInBackground(URL... params) {
URL url = params[0];
Bitmap image = null;
try {
image = BitmapFactory.decodeStream(url.openConnection().getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
return image;
}
//Runs on the UI Thread
@Override
protected void onPostExecute(Bitmap image) {
myPd_ring.dismiss();
if (image == null){
Toast.makeText(SingleWall.this, "Setting WallPaper Failed!!", Toast.LENGTH_LONG).show();
}
else{
//set image here
try {
SingleWall.this.wallManager.setBitmap(image);
Toast.makeText(SingleWall.this, "Wallpaper Set Successfully!!", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(SingleWall.this, "Setting WallPaper Failed!!", Toast.LENGTH_LONG).show();
}
}
}
}
答案 1 :(得分:0)
使用AsyncTask,可能会出现空指针,因为您正在尝试在任务处理期间更新UI。您可能需要在AsyncTask中使用类似的东西:
activity.runOnUiThread(new Runnable() {
public void run() {
activity.doSomeSpecialUIWork();
}
});
}
希望有效 - 当我在AsyncTask中获取奇怪的空指针时,这就是为我解决的问题。
以下是其他帖子的示例:how to use runOnUiThread
对于您的具体代码,可能是:
setWallbtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
activity.runOnUiThread(new Runnable() {
public void run() {
final ProgressDialog myPd_ring=ProgressDialog.show(SingleWall.this, "Setting wallpaper", "", true);
// TODO Auto-generated method stub
WallpaperManager wallManager = WallpaperManager.getInstance(getApplicationContext());
try {
image = BitmapFactory.decodeStream(url.openConnection().getInputStream());
wallManager.setBitmap(image);
Toast.makeText(SingleWall.this, "Wallpaper Set Successfully!!", Toast.LENGTH_SHORT).show();
myPd_ring.dismiss();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Toast.makeText(SingleWall.this, "Setting WallPaper Failed!!", Toast.LENGTH_SHORT).show();
myPd_ring.dismiss();
}
}
});
}
}
});