android - AsyncTask不会在Android 2.3 Andengine中引发异常

标签 android multithreading andengine

我有一个可以在Google Nexus(Android 4.2)中成功运行的代码。但是当我昨天在较低版本的android 2.3.5中尝试过它时,它抛出了异常。

请帮助我解决同样的问题。

细节。

我创建了一个DownloadHelper类,可帮助我从Internet将文件下载到手机中的某个位置。
此类实习生称为子类DownloadFile extends AsyncTask。当我尝试创建DownloadFile对象时,将引发异常。

下面是DownloadHeper的代码

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;

import org.andengine.entity.text.Text;
import org.andengine.ui.activity.BaseGameActivity;

import com.gretrainer.gretrainer.StartingScreen;

import android.os.AsyncTask;
import android.os.Environment;
import android.util.Log;

public class DownloadHelper {
    public void loadFile(String url,Text loadingT,BaseGameActivity activity1,String _filename,int _tag){
        DownloadFile downloadFile;
        try {
            downloadFile = new DownloadFile();
            loadingText = loadingT;
            activity = activity1;
            downloadFile.execute(url);
            StartingPercent = 0;
            EndingPercent = 100;
            filename = _filename;
            tag = _tag;
        } catch (Exception e) {
            Log.d("exec",e.getLocalizedMessage());
        }



    }

    private int tag;
    private String filename;
    private float StartingPercent;
    private float EndingPercent;
    private BaseGameActivity activity;
    private Text loadingText;
    private class DownloadFile extends AsyncTask<String,Integer,String>{

        public DownloadFile(){

        }

        @Override
        protected String doInBackground(String... sUrl) {
            try {
                URL url = new URL(sUrl[0]);
                URLConnection connection = url.openConnection();
                connection.connect();
                // this will be useful so that you can show a typical 0-100% progress bar
                int fileLength = connection.getContentLength();

                // download the file
                InputStream input = new BufferedInputStream(url.openStream());
                OutputStream output = new FileOutputStream(Environment.getExternalStorageDirectory().toString().concat(File.separator + filename));


                byte data[] = new byte[1024];
                long total = 0;
                int count;
                while ((count = input.read(data)) != -1) {
                    total += count;
                    // publishing the progress....
                    publishProgress((int) (total * 100 / fileLength));
                    output.write(data, 0, count);
                }

                output.flush();
                output.close();
                input.close();
                StartingScreen act = (StartingScreen)activity;
                act.onLoadFileComplete(tag);
            } catch (Exception e) {
                String message = e.getLocalizedMessage();
                Log.d("hello",message);
            }
            return null;
        }

          @Override
            protected void onPreExecute() {
                super.onPreExecute();
            }

            @Override
            protected void onProgressUpdate(Integer... progress) {
                super.onProgressUpdate(progress);
                activity.runOnUiThread(new Runnable(){

                    @Override
                    public void run() {
                        // TODO Auto-generated method stub

                    }

                });
                //loadingText.setText(StartingPercent + ((EndingPercent - StartingPercent) / 100) * progress[0] + "%");
            }


    }
}

当执行行downloadFile = new DownloadFile()时,将引发异常。

Exception的详细信息如下所示。
UpdateThread interrupted. Don't worry - this EngineDestroyedException is most likely expected!
org.andengine.engine.Engine$EngineDestroyedException

它返回到onCreateScene的最后一行。但该应用程序被冻结。
在新的android OS(4.2)中工作正常

请检查

异常发生时的整个日志
04-07 17:46:42.498:W/dalvikvm(2552):异常Ljava/lang/RuntimeException;初始化Landroid/os/AsyncTask时抛出;
04-07 17:47:06.891:E/AndEngine(2552):StartingScreen.onPopulateScene失败。 @(线程:'GLThread 11')
04-07 17:47:06.891:E/AndEngine(2552):java.lang.ExceptionInInitializerError
04-07 17:47:06.891:E/AndEngine(2552):在com.gretrainer.gretrainer.AppHelpers.DownloadHelper.loadFile(DownloadHelper.java:24)
04-07 17:47:06.891:E/AndEngine(2552):位于com.gretrainer.gretrainer.StartingScreen.onPopulateScene(StartingScreen.java:102)
04-07 17:47:06.891:E/AndEngine(2552):在org.andengine.ui.activity.BaseGameActivity $ 2.onCreateSceneFinished(BaseGameActivity.java:154)
04-07 17:47:06.891:E/AndEngine(2552):位于com.gretrainer.gretrainer.StartingScreen.onCreateScene(StartingScreen.java:91)
04-07 17:47:06.891:E/AndEngine(2552):在org.andengine.ui.activity.BaseGameActivity $ 3.onCreateResourcesFinished(BaseGameActivity.java:169)
04-07 17:47:06.891:E/AndEngine(2552):在com.gretrainer.gretrainer.StartingScreen.onCreateResources(StartingScreen.java:68)
04-07 17:47:06.891:E/AndEngine(2552):位于org.andengine.ui.activity.BaseGameActivity.onCreateGame(BaseGameActivity.java:181)
04-07 17:47:06.891:E/AndEngine(2552):位于org.andengine.ui.activity.BaseGameActivity.onSurfaceCreated(BaseGameActivity.java:110)
04-07 17:47:06.891:E/AndEngine(2552):位于org.andengine.opengl.view.EngineRenderer.onSurfaceCreated(EngineRenderer.java:80)
04-07 17:47:06.891:E/AndEngine(2552):在android.opengl.GLSurfaceView $ GLThread.guardedRun(GLSurfaceView.java:1352)
04-07 17:47:06.891:E/AndEngine(2552):在android.opengl.GLSurfaceView $ GLThread.run(GLSurfaceView.java:1122)
04-07 17:47:06.891:E/AndEngine(2552):由以下原因引起:java.lang.RuntimeException:无法在未调用Looper.prepare()的线程内创建处理程序
04-07 17:47:06.891:E/AndEngine(2552):位于android.os.Handler。(Handler.java:121)
04-07 17:47:06.891:E/AndEngine(2552):位于android.os.AsyncTask $ InternalHandler。(AsyncTask.java:421)
04-07 17:47:06.891:E/AndEngine(2552):位于android.os.AsyncTask $ InternalHandler。(AsyncTask.java:421)
04-07 17:47:06.891:E/AndEngine(2552):位于android.os.AsyncTask。(AsyncTask.java:152)
04-07 17:47:06.891:E/AndEngine(2552):...还有11个
04-07 17:47:06.891:D/AndEngine(2552):StartingScreen.onSurfaceChanged(Width = 320,Height = 480)@(线程:'GLThread 11')
04-07 17:47:07.102:D/dalvikvm(2552):GC_FOR_MALLOC释放142K,42%释放3211K/5447K,外部1K/512K,暂停26ms
04-07 17:47:07.102:I/dalvikvm-heap(2552):将堆(片段大小写)增加到6.457MB以分配1382416字节
04-07 17:47:07.222:D/dalvikvm(2552):GC_CONCURRENT释放了2K,34%释放了4559K/6855K,外部1K/512K,暂停了3ms + 4ms
04-07 17:47:07.222:D/AndEngine(2552):StartingScreen.onResumeGame @(线程:'main')
04-07 17:47:07.292:E/Database(2552):close()从未在数据库'/data/data/com.gretrainer.gretrainer/databases/GreApp'上显式调用
04-07 17:47:07.292:E/Database(2552):android.database.sqlite.DatabaseObjectNotClosedException:应用程序未关闭此处打开的游标或数据库对象
04-07 17:47:07.292:E/Database(2552):位于android.database.sqlite.SQLiteDatabase。(SQLiteDatabase.java:1960)
04-07 17:47:07.292:E/Database(2552):位于android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:906)
04-07 17:47:07.292:E/Database(2552):位于android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:940)
04-07 17:47:07.292:E/Database(2552):位于android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:933)
04-07 17:47:07.292:E/Database(2552):位于android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:744)
04-07 17:47:07.292:E/Database(2552):位于android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:203)
04-07 17:47:07.292:E/Database(2552):位于android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:118)
04-07 17:47:07.292:E/Database(2552):位于android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:198)
04-07 17:47:07.292:E/Database(2552):在com.gretrainer.gretrainer.AppHelpers.DatabaseHandler.getWordsCount(DatabaseHandler.java:213)
04-07 17:47:07.292:E/Database(2552):位于com.gretrainer.gretrainer.StartingScreen.onPopulateScene(StartingScreen.java:100)
04-07-07:47:07.292:E/数据库(2552):在org.andengine.ui.activity.BaseGameActivity $ 2.onCreateSceneFinished(BaseGameActivity.java:154)
04-07 17:47:07.292:E/Database(2552):位于com.gretrainer.gretrainer.StartingScreen.onCreateScene(StartingScreen.java:91)
04-07 17:47:07.292:E/Database(2552):at org.andengine.ui.activity.BaseGameActivity $ 3.onCreateResourcesFinished(BaseGameActivity.java:169)
04-07 17:47:07.292:E/Database(2552):位于com.gretrainer.gretrainer.StartingScreen.onCreateResources(StartingScreen.java:68)
04-07 17:47:07.292:E/Database(2552):位于org.andengine.ui.activity.BaseGameActivity.onCreateGame(BaseGameActivity.java:181)
04-07 17:47:07.292:E/Database(2552):位于org.andengine.ui.activity.BaseGameActivity.onSurfaceCreated(BaseGameActivity.java:110)
04-07 17:47:07.292:E/Database(2552):位于org.andengine.opengl.view.EngineRenderer.onSurfaceCreated(EngineRenderer.java:80)
04-07 17:47:07.292:E/数据库(2552):在android.opengl.GLSurfaceView $ GLThread.guardedRun(GLSurfaceView.java:1352)
04-07 17:47:07.292:E/数据库(2552):在android.opengl.GLSurfaceView $ GLThread.run(GLSurfaceView.java:1122)

最佳答案

这只是一个猜测,但是一些Exceptions得出的结论是您没有正确执行AsyncTask(请参阅Can't create handler inside thread that has not called Looper.prepare()。我不建议您自己调用Looper.prepare(),而是在另一个线程上执行Asynctask。因此,

downloadFile = new DownloadFile();
loadingText = loadingT;
activity = activity1;
downloadFile.execute(url);
StartingPercent = 0;
EndingPercent = 100;
filename = _filename;
tag = _tag;

尝试这样的操作(顺便说一句,您正在访问任务中的一些变量,应该早些对其进行初始化):
loadingText = loadingT;
activity = activity1;   
StartingPercent = 0;
EndingPercent = 100;
filename = _filename;
tag = _tag; 
runOnUiThread(new Runnable() {
    @Override
    public void run() {
        new DownloadFile().execute(url);
    }
});

我对AsyncTask s的经验是,它们不应在正常的Update Thread上运行,因为该线程仅用于刷新屏幕,因此请尝试在UIThread上运行它(因为您不是直接在任务内显示数据)。

关于android - AsyncTask不会在Android 2.3 Andengine中引发异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15846668/

相关文章:

java - 如何在碰撞时改变 Sprite 图像

android - Android音频-计算两个设备之间的距离

java - OpenCV 相机预览中未显示 mask

c# - 尽管 UI 存在于 STAThread 中,为什么 Control.(Begin)Invoke 是必要的?

java - JDBC连接并发充足性

java - TimerHandler 每秒使用受限随机生成器

android - 如何更改 Android 中涟漪效应的持续时间?

php - 使用 PHP 向 Android 发送和接收变量

c# - 线程 : BeginInvoke howto add a complete ListviewItem?

android - 在 Andengine 中移动 Sprite