[英]Android background task for UI
I'm developing an app under Android which handles bitmap and apply GPU filters on a bitmap. 我正在Android下开发一款可处理位图并在位图上应用GPU过滤器的应用。 As it can be slow, I have decided to set a "default image", like a fake picture, which is displayed until the picture I want to filtered is done.
由于速度可能很慢,因此我决定设置一个“默认图像”,例如假图片,该默认图片会一直显示到要过滤的图片完成为止。
Prior to this, I was expecting the bitmap to be modified before being displayed, but it's not offering a nice user experience. 在此之前,我期望位图在显示之前会被修改,但是它并不能提供良好的用户体验。
The issue is that I have a warning at system level saying : 问题是我在系统级别显示警告:
System.err﹕ android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
I have seen a few threads which indicate that I have to use the runOnUiThread
, but I do not know how to make it work.. here is the code of my apps 我已经看到一些线程,这些线程指示我必须使用
runOnUiThread
,但是我不知道如何使其工作..这是我的应用程序的代码
The activity FilterActivity
, receives an URI which contains a path to a file. 活动
FilterActivity
接收一个URI,该URI包含文件的路径。 The FilterPreview
method is handling the class who will manage to queue the action I want to do. FilterPreview
方法正在处理将设法将我要执行的操作排队的类。
public class FiltersActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_filters);
mFiltersView = (ListView) findViewById(R.id.filters_place_holder);
ViewGroup.LayoutParams params = mFiltersView.getLayoutParams();
Intent intent = getIntent();
mSnapShotUri = intent.getData();
getBitmapFromURI(mSnapShotUri);
....
private void getBitmapFromURI(Uri uri) {
try {
mSnapShot = MediaStore.Images.Media.getBitmap(this.getContentResolver(), uri);
}
catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "File not found");
}
finally {
mPreviewBitmap = Bitmap.createScaledBitmap(mBitmap, PreviewSizeWidth, PreviewSizeHeight, false);
FiltersPreview();
}
}
private void FiltersPreview() {
boolean mPreview = true;
mFiltersView.setAdapter(new CameraImageFiltersAdapter(this, mSnapShot, mPreviewBitmap, mPreview));
mFiltersView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
CameraFiltersFactory effect = (CameraFiltersFactory) v.findViewById(R.id.filteredImage).getTag();
effect.save(new GPUImage.OnPictureSavedListener() {
@Override public void onPictureSaved(Uri uri) {
Intent previewIntent = new Intent(FiltersActivity.this, PreviewActivity.class);
previewIntent.setData(uri);
startActivityForResult(previewIntent, 0);
}
});
}
});
}
In my app, the part below is slowing down the UI, as I do not use a background task/thread to update the UI. 在我的应用程序中,下面的部分正在减慢UI的速度,因为我没有使用后台任务/线程来更新UI。
mFiltersView.setAdapter(new CameraImageFiltersAdapter(this, mSnapShot, mPreviewBitmap, mPreview));
CameraImageFiltersAdapter
class ( stub_id
is the fake image displayed during the process of applying filters) CameraImageFiltersAdapter
类( stub_id
是在应用滤镜的过程中显示的伪图像)
public CameraImageFiltersAdapter(Context c, Bitmap original, Bitmap current, boolean isPreview) {
....
mExecutorService = Executors.newFixedThreadPool(5);
}
@SuppressLint("InflateParams")
public View getView(int position, View convertView, ViewGroup parent) {
ImageView filteredImage;
if (convertView == null) {
convertView = LayoutInflater.from(mContext).inflate(R.layout.list_item_filter, null);
filteredImage = (ImageView) convertView.findViewById(R.id.filteredImage);
filteredImage.setImageResource(stub_id);
queueFiltered(filteredImage, position);
}
return convertView;
}
private void queueFiltered(ImageView imageView, int position) {
CameraFiltersFactory holder = new CameraFiltersFactory(mContext, imageView);
mExecutorService.submit(new FilterLoader(holder, position));
}
class FilterLoader implements Runnable {
CameraFiltersFactory FilterToLoad;
int FilterPosition;
FilterLoader(CameraFiltersFactory FilterToLoad, int pos) {
this.FilterToLoad = FilterToLoad;
this.FilterPosition = pos;
}
@Override
public void run() {
try {
FilterToLoad.setResources(mOriginalBitmap, mCurrentBitmap, mFilterIds[FilterPosition], mPreview);
} catch (Throwable th) {
th.printStackTrace();
}
}
}
Any idea? 任何想法?
You can not make changes to views in your ThreadPool's threads, use a main thread handler to post a message and handle it in main thread. 您无法在ThreadPool的线程中更改视图,而不能使用主线程处理程序来发布消息并在主线程中对其进行处理。 Or using AsyncTask like this Processing Bitmaps Off the UI Thread
或者像这样使用AsyncTask 在UI线程中处理位图
pass the activity as a parameter for the adapter and then call: 将活动作为适配器的参数传递,然后调用:
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
//change the image here
}
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.