2012-07-20 41 views
0

觸發我在這裏得到一個java.lang.NullPointerException錯誤時:NullPointerException異常上SQLiteOpenHelper.getWritableDatabase從的AsyncTask

com.mysite.datasources.ArticlesDataSource.open(ArticlesDataSource.java:88) 

的代碼是這樣的:

public void open() throws SQLException 
{ 
    database = dbHelper.getWritableDatabase(); //this is line 88 
} 

它正在從importArticles()函數調用內ArticlesDataSource

從我SplashScreenActivity調用時能正常工作:

articlesDataSource = new ArticlesDataSource(context); 
try { 
    articlesDataSource.importArticles(Section.currentSection, false); 
    ... 

但是,當我試圖從我的ImportArticlesAsync(內MainActivity)調用它,我得到了NullPointerException錯誤。

//This is within my MainActivity class 

    //... 
    ImportArticlesAsync importArticlesAsync = new ImportArticlesAsync(this); 
    importArticlesAsync.execute(""); 
} 

private class ImportArticlesAsync extends AsyncTask<String, Void, String> 
{ 

    Context mContext; 
    //ProgressDialog waitSpinner; 
    private ArticlesDataSource articlesDataSource; 
    //ConfigurationContainer configuration = ConfigurationContainer.getInstance(); 

    public ImportArticlesAsync(Context context) { 
     mContext = context; 
     //waitSpinner = new ProgressDialog(this.context); 
    } 

    @Override 
    protected String doInBackground(String... params) 
    { 
     //IMPORTS THE ARTICLES FROM THE RSS FEED (adds or updates) 
    //tried just mContext //notice 
    //tried mContext.getApplicationContext() //ERROR/crash 

     articlesDataSource = new ArticlesDataSource(mContext); 
     try { 
      articlesDataSource.importArticles(Section.currentSection, false); 
     } catch (Exception e) { 
      Toast toast = Toast.makeText(
        mContext, 
        "NOTICE: Could not import/update " + Section.currentSection.toString() + " articles.", 
        Toast.LENGTH_LONG); 
      toast.show(); 
     } 
     return null; 
    } 


    @Override 
    protected void onPostExecute(String result) { 

     //loads article from database to the list 
     loadArticlesIntoList(Section.currentSection); 
} 
} 

從我讀過的,大多數人認爲它必須是不正確的上下文。但是 - 我還沒有真正理解上下文,並且嘗試了我能想到的各種方式(並且閱讀了許多關於上下文的內容)。


我在圖試圖/我的 「代碼」 清潔工解釋:

//YAY this works! 
SplashScreenActivity 
    -LoadApplication (AsyncTask) 
     -doInBackground 
      articlesDataSource = new ArticleDataSource(context); 
      articlesDataSource.importArticles(Section.currentSection, false); 

//BOO, this doesn't work! 
MainActivity 
    -ImportArticlesAsync 
     -doInBackground (AsyncTask) 
      articlesDataSource = new ArticlesDataSource(context); 
      articlesDataSource.importArticles(Section.currentSection, false); 

每請求 - dbHelper得到在此處設置:

private SQLiteDatabase database; 
private DbHelper dbHelper; 
private PhotosDataSource photosdatasource; 
private SectionsDataSource sectionsdatasource; 

public ArticlesDataSource(Context context) 
{ 
    mContext = context; 
    dbHelper = new DbHelper(mContext); 
    photosdatasource = new PhotosDataSource(context); 
    sectionsdatasource = new SectionsDataSource(context); 
} 

public void open() throws SQLException 
{ 
    database = dbHelper.getWritableDatabase(); 
} 

代碼:

com.mysite.news

com.mysite.models

com.mysite.datasources

com.mysite。UTILITES

的AndroidManifest.xml - http://pastebin.com/hHF86f4d


ERROR:

07-20 21:33:26.721:W /系統.err(8260):java.lang.NullPointerException 07-20 21:33:26.721:W/System.err (8260):at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:203) 07-20 21:33:26.721:W/System.err(8260):at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper .java:118) 07-20 21:33:26.721:W/System.err(8260):at com.mysite.datasources.ArticlesDataSource.open(ArticlesDataSource.java:88) 07-20 21:33:26.721 :W/System.err(8260):at com.mysite.datasources.ArticlesDataSource.importArticles(ArticlesDataSource.java:101) 07-20 21:33:26.721:W/System.err(8260):at com.mysite .news.MainActivity $ ImportArticlesAsync.doInBackground(MainActivity.java:194) 07-20 21:33:26.721:W/System.err(8260):at com.mysite.news.MainActivity $ ImportArticlesAsync.doInBackground(MainActivity.java :1) 07-20 21:33:26.721:W/System.err(8260):在android.os.AsyncTask $ 2.call(AsyncT ask.java:185) 07-20 21:33:26.721:W/System.err(8260):在java.util.concurrent.FutureTask $ Sync.innerRun(FutureTask.java:306) 07-20 21: 33:26.721:W/System.err(8260):at java.util.concurrent.FutureTask.run(FutureTask.java:138) 07-20 21:33:26.721:W/System.err(8260):at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088) 07-20 21:33:26.721:W/System.err(8260):位於java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor。的java:581) 07-20 21:33:26.721:W/System.err的(8260):在java.lang.Thread.run(Thread.java:1019)


SectionSelectedListener.java

package com.mysite.news; 

import android.view.View; 
import android.widget.AdapterView; 
import android.widget.AdapterView.OnItemSelectedListener; 

public class SectionSelectedListener implements OnItemSelectedListener 
{ 
    public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) 
    { 
     MainActivity mainActivity = new MainActivity(); 
     mainActivity.sectionSelected();  
    } 

    public void onNothingSelected(AdapterView<?> arg0) { 
     // Do nothing  
    } 

} 
+0

它好像dbHelper變量爲空。你能告訴我們價值分配的地方嗎? – mfrankli 2012-07-20 20:25:32

+0

假設DbHelper是一個覆蓋SQLiteDatabaseHelper的類是否安全? – mfrankli 2012-07-20 20:35:18

+0

mfrankli - 「公共類DbHelper擴展SQLiteOpenHelper」 – Dave 2012-07-20 20:47:10

回答

1

您傳遞給AsyncTask的參考文獻Contextnull。您只需要調用sectionSelected()方法即可實例化新的MainActivity。你不應該自己實例化一個活動!

最簡單的解決辦法是簡單的做一個匿名內部類作爲MainActivity聽衆:

sectionsSpinner.setOnItemSelectedListener(new OnItemSelectedListener() 
{ 
    public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) { 
     sectionSelected();  
    } 

    public void onNothingSelected(AdapterView<?> arg0) { 
     // Do nothing  
    } 

}); 
+0

完美 - 謝謝 - (合理!) – Dave 2012-07-21 15:41:57

+0

@Dave快速複製粘貼留下的圓括號:)。將文章的導入移動到另一個線程也應該解決您以前的問題,ListView不會消失。 – Luksprog 2012-07-21 15:45:31

+0

Luksprog - 我認爲我的文章導入是在不同的線程中,對吧? – Dave 2012-07-21 20:12:23

0

嘗試從AsyncTaskdoInBackground(..)方法移動此行articlesDataSource = new ArticlesDataSource(mContext);AsyncTaskonPreExecute()方法。這樣的事情:

private class ImportArticlesAsync extends AsyncTask<String, Void, String> 
{ 

Context mContext; 
//ProgressDialog waitSpinner; 
private ArticlesDataSource articlesDataSource; 
//ConfigurationContainer configuration = ConfigurationContainer.getInstance(); 

public ImportArticlesAsync(Context context) { 
    mContext = context; 
    //waitSpinner = new ProgressDialog(this.context); 
} 

@Override 
protected void onPreExecute() 
{ 
    articlesDataSource = new ArticlesDataSource(mContext); 
} 


@Override 
protected String doInBackground(String... params) 
{   
    try { 
     articlesDataSource.importArticles(Section.currentSection, false); 
    } catch (Exception e) { 
     Toast toast = Toast.makeText(
       mContext, 
       "NOTICE: Could not import/update " + Section.currentSection.toString() + " articles.", 
       Toast.LENGTH_LONG); 
     toast.show(); 
    } 
    return null; 
} 


@Override 
protected void onPostExecute(String result) { 

    //loads article from database to the list 
    loadArticlesIntoList(Section.currentSection); 
} 
} 

我認爲這將解決您的問題。

+0

我試過了,但是我得到了完全相同的錯誤。 – Dave 2012-07-20 20:49:39

+0

你在哪裏保存你的數據庫?如果將其保存在項目的資產文件夾中,那麼您只具有對文件的讀取權限而不能寫入。 – Angelo 2012-07-20 20:51:42

+1

您是否還在'AsyncTask'中傳遞正確的上下文作爲參數?也許你仍然在通過'SplashScreenActivity's'上下文,而不是'MainActivity's'上下文,這是你的第二個用例中正確的。 – Angelo 2012-07-20 20:58:59

0

將dbHelper變量從您的ArticlesDataSource類移動到您的Activity中,確保它在您創建AsyncTasks之前被初始化。

+0

我很抱歉,但我不遵循你所說的話。第一次運行它時,這一切都很好,但第二次,從MainActivity(而不是SplashScreenActivity)開始,它失敗了。 – Dave 2012-07-20 21:12:12

相關問題