【问题标题】:Android program stops at doInBackground and doesn't come to onPostExecuteAndroid 程序停在 doInBackground 并没有来 onPostExecute
【发布时间】:2015-01-02 20:21:51
【问题描述】:

我的程序在 doInBackground 之后崩溃并且没有到达 onPostExecute。

我的活动代码的相关部分是这样的:

public static class News {
    private String title;
    private String content;
    private Bitmap image;

    public News(String nTitle, String nContent, Bitmap nImage){
        title = nTitle;
        content = nContent;
        image = nImage;
    }
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_news);
    final AsyncTask task = new DatabaseConnection(this, Method.GET_ALL_NEWS).execute();
    try {
        task.wait();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}


public final void fillListView(List<News> news){
    recentNews = news;
    if(recentNews != null && !recentNews.isEmpty()){
        ((ListView)findViewById(R.id.lvNews)).setOnItemClickListener(this);
        final int size = recentNews.size();
        final String newsTitles[] = new String[size];
        for(int i=0; i<size; ++i)
            newsTitles[i] = recentNews.get(i).title;

        ((ListView)findViewById(R.id.lvNews)).setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, newsTitles));
    }
}

@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    final News selectedNews = recentNews.get(position);
    startActivity(new Intent(this, ANewsActivity.class)
        .putExtra("title", selectedNews.title)
        .putExtra("content", selectedNews.content)
        .putExtra("image", BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher)));

}

我的 AsyncTask 代码的相关部分是这样的:

public DatabaseConnection(Context nContext, Method nMethod){
    method = nMethod;
    context = nContext;
}

@Override
protected void onPreExecute() {
    progressDialog = new ProgressDialog(context);
    progressDialog.setMessage(context.getString(R.string.database_connection_wait_message));
    progressDialog.setTitle(R.string.database_connection_wait_title);
    progressDialog.show();
}

@SuppressWarnings("incomplete-switch")
@Override
protected Void doInBackground(String... params) {
    if(method != Method.NONE){
        open();
        try{
            switch(method){
            case GET_ALL_NEWS:
                final ResultSet rs = conn.createStatement().executeQuery("select baslik, metin, resim from haberler");
                news =  new ArrayList<News>();
                while(rs.next())
                    news.add(new News(rs.getString(1), rs.getString(2), BitmapFactory.decodeStream(rs.getBlob(3).getBinaryStream())));
                break;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            close();
        }
    }
    return null;
}

@SuppressWarnings("incomplete-switch")
@Override
protected void onPostExecute(Void temp) {
    if (progressDialog.isShowing()){
        progressDialog.dismiss();
        switch(method){
        case GET_ALL_NEWS:
            ((NewsActivity)context).fillListView(news);
            break;
        }
        method = Method.NONE;
    }
}

我希望 UI 线程一直等到数据库操作完成。 顺便说一句,变量等没有初始化问题,数据库返回正确的信息,我的“新闻”变量被正常填充。

顺便说一句,我再次意识到它在 PHONE 上工作,有趣的是在 EMULATOR 上卡住了(如果我删除了 wait() 方法及其在主线程代码上的 try-catch 块)。

【问题讨论】:

标签: android android-asynctask remote-access progressdialog


【解决方案1】:

如果没有 logcat 输出,很难说是什么导致了崩溃,但它很可能是应用程序的主线程,因为您在 onCreate() 中调用了 .wait() 方法。您的 onCreate() 不能等待 - 它必须初始化并退出,否则您将阻塞应用程序的主线程并破坏 AsyncTask 的目的。

【讨论】:

  • 如果我删除了带有 try-catch 块的 wait() 方法,那么程序会卡在数据库上的 open() 方法中。 LogCat 的输出类似于“01-02 20:30:01.900: I/Choreographer(1772): Skipped 31 frames! The application may be doing too much work on its main thread.” 这样的消息不断收到,ProgressDialog 正在运行在屏幕上。
  • 这表明您的数据库在主线程上打开或操作的另一个问题。
  • 没有代码可以直接从主线程调用 open() 远程数据库方法。正如我所提到的,删除 wait() 并在手机上运行应用程序解决了我的问题。但我仍然想知道为什么模拟器会失败。
  • 模拟器端应该没有区别。您提到数据库是远程的;你这是什么意思?它是由ContentProvider 包装的,还是您使用其他类型的机制来包装数据库?如果您通过网络链接使用某些东西,则模拟器将具有与真实设备不同的连接性。您是否尝试过在模拟器中跳过open() 调用?
  • Remote 表示它不是 SQLite,它是远程服务器上的 MySql。程序使用 Internet 访问它。我试图跨过去,但没有成功。
猜你喜欢
  • 2012-06-18
  • 1970-01-01
  • 2021-02-22
  • 1970-01-01
  • 2016-10-07
  • 2018-11-23
  • 1970-01-01
  • 1970-01-01
  • 2012-11-05
相关资源
最近更新 更多