使用 aSyncTask 优化位图加载
我一直在尝试优化我的单线程应用程序,该应用程序加载一堆组成大位图的图块。当应用程序将新图块加载到系统内存中时,它变得非常缓慢。我现在正在尝试使用异步任务来实现此目的。该应用程序在 onDraw 调用的方法中检测哪个图块位于左上角,创建一个包含 Assets 文件夹中位图路径的字符串,然后在绘制之前检查位图是否为空。如果为空,则将其加载到内存中。我的想法是在 DoBackground 中处理位图,并在 postExecute 中触发视图无效以显示异步加载的位图。有几个问题:
1.) 我可以为每个位图执行 aSync 任务吗? (这个语句: new myAsyncTaskManager().execute(bitmapPath); 如果没有,最好的方法是什么,因为 aSync 唯一要做的就是将位图加载到内存中?
2.)是否可以设置优先级aSyncTask 如果位图加载太慢?
3.) 有没有更好的方法来解决这个问题?我确定是位图加载,而不是画布绘制减慢了应用程序的速度。
我的临时异步代码:
private class myAsyncTaskManager extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... bitmapPath) {
Log.e("sys","i ran using aTask");
try {
bitmapArray[rectBeingDrawn] = BitmapFactory.decodeStream(assetManager.open(imagePathToLoad));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} return null;
}
@Override
protected void onPostExecute(String result) {
// execution of result of Long time consuming operation
mCampusMap.invalidate();
}
}
I have been trying to optimize my single thread app which loads a bunch of tiles that makeup a large bitmap. The app was becoming very sluggish when it would load the new tiles into system memory. Im now looking trying to use Async Tasks for this purpose. The app detects which tile is in the top left in a method called by onDraw, creates a string that contains the path of the bitmap in the Assets folder, and then checks to see if the bitmap is null before drawing. If it is null, it will load it into memory. My idea was to process the bitmap in DoBackground, and in postExecute trigger a view invalidate to display the async loaded bitmap. Few questions:
1.) can i execute my aSync task for each bitmap? (this statement: new myAsyncTaskManager().execute(bitmapPath); if not, what is the best way to go about it since the only thing aSync will do is just load bitmaps into memory?
2.) Is it possible to set the priority aSyncTask if the bitmaps load too slow?
3.) Is there a better way to go about this? im certain it is the bitmap loading, and not the canvas drawing that slows down the app.
My temporary aSync code:
private class myAsyncTaskManager extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... bitmapPath) {
Log.e("sys","i ran using aTask");
try {
bitmapArray[rectBeingDrawn] = BitmapFactory.decodeStream(assetManager.open(imagePathToLoad));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} return null;
}
@Override
protected void onPostExecute(String result) {
// execution of result of Long time consuming operation
mCampusMap.invalidate();
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
为您的全新问题添加新答案:)
取决于位图的数量。你有多少个?您不想创建数十个线程。毕竟,您的硬件上只有一个核心,因此拥有多个线程不会给您带来任何好处 - 上下文切换只会淹没它。如果您有大量位图,您可能需要一个位图队列并对其进行处理。为此,线程和处理程序实际上会更好。
是的。一般来说,我将工作线程的优先级设置为比主线程低一级。
Adding a new answer to your completely new question :)
Depends on the amount of bitmaps. How many do you have? You don't want to create dozens of threads. After all, you only have one core on your hardware, so having multiple threads won't buy you anything - the context switching would just drown it out. If you have tons of bitmaps, you may want to have a queue of bitmaps and work through it. For that, a Thread and Handler would actually be better.
It is. Generally, I set worker threads one priority level lower than the main thread.
等等,你正在调用 bitmapLoaderThread.run() 吗?很难弄清楚发生了什么,因为这些是没有上下文的代码片段(什么线程正在运行?什么函数?),但你不调用 run() - 这是操作系统的工作!要启动新线程,请调用 start() - 这将创建新线程并调用其 run() 函数。如果你直接调用run,你仍然是在你自己的线程中调用它!
除此之外 - 如何在两个线程之间进行握手?工作线程如何告诉主线程位图已加载?您可以使用 Handler 来实现此目的,也可以使用 AsyncTask 来完全代替 Thread。
Wait, you're calling bitmapLoaderThread.run()? It's kind of hard to figure out what's going on because these are code snippets with no context (what thread is something running on? What function?), but you don't call run() - that's the operating system's job! To start a new thread, you call start() - this will create the new thread and call its run() function. If you call run directly, you're still calling it in your own thread!
Other than that - how do you do the handshake between the two threads? How does the worker thread tell the main thread that the bitmap is loaded? You can use a Handler for that, or you can use an AsyncTask instead of the Thread altogether.