导航时随机崩溃

时间:2012-03-07 02:18:41

标签: android listview logcat

我已将我的活动设置为listview-> Listview-> listview->表格布局 - >等等 在导航应用程序应用程序时工作得很好。但是程序随机崩溃只是时间问题。

03-06 21:12:29.350: W/dalvikvm(7132): threadid=3: thread exiting with uncaught exception (group=0x4001b188)
03-06 21:12:29.350: E/AndroidRuntime(7132): Uncaught handler: thread main exiting due to uncaught exception
03-06 21:12:29.370: E/AndroidRuntime(7132): java.lang.NullPointerException
03-06 21:12:29.370: E/AndroidRuntime(7132):     at wanted.pro.madlibs.title.onListItemClick(title.java:55)
03-06 21:12:29.370: E/AndroidRuntime(7132):     at android.app.ListActivity$2.onItemClick(ListActivity.java:312)
03-06 21:12:29.370: E/AndroidRuntime(7132):     at android.widget.AdapterView.performItemClick(AdapterView.java:284)
03-06 21:12:29.370: E/AndroidRuntime(7132):     at android.widget.ListView.performItemClick(ListView.java:3285)
03-06 21:12:29.370: E/AndroidRuntime(7132):     at android.widget.AbsListView$PerformClick.run(AbsListView.java:1640)
03-06 21:12:29.370: E/AndroidRuntime(7132):     at android.os.Handler.handleCallback(Handler.java:587)
03-06 21:12:29.370: E/AndroidRuntime(7132):     at android.os.Handler.dispatchMessage(Handler.java:92)
03-06 21:12:29.370: E/AndroidRuntime(7132):     at android.os.Looper.loop(Looper.java:123)
03-06 21:12:29.370: E/AndroidRuntime(7132):     at android.app.ActivityThread.main(ActivityThread.java:4363)
03-06 21:12:29.370: E/AndroidRuntime(7132):     at java.lang.reflect.Method.invokeNative(Native Method)
03-06 21:12:29.370: E/AndroidRuntime(7132):     at java.lang.reflect.Method.invoke(Method.java:521)
03-06 21:12:29.370: E/AndroidRuntime(7132):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
03-06 21:12:29.370: E/AndroidRuntime(7132):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
03-06 21:12:29.370: E/AndroidRuntime(7132):     at dalvik.system.NativeStart.main(Native Method)
03-06 21:12:29.380: I/dalvikvm(7132): threadid=7: reacting to signal 3
03-06 21:12:29.380: E/dalvikvm(7132): Unable to open stack trace file '/data/anr/traces.txt': Permission denied

从logcat看起来问题出现在我的onlistitemclick中。虽然我不知道为什么它会工作一段时间然后没有。下面是我用于其中一个列表视图的代码。

public class title extends ListActivity {
    private PopupWindow pw;
    public static int titleClick;
    private dbadapter mydbhelper;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.category_list);
        mydbhelper = new dbadapter(this);
        mydbhelper.open();
        fillData();
    }
    private void fillData() {

        Cursor t = mydbhelper.getTitles();
            startManagingCursor(t);

     // Create an array to specify the fields we want to display in the list (TITLE,DATE,NUMBER)
        String[] from = new String[] {dbadapter.KEY_TITLEDESC};

        // an array of the views that we want to bind those fields to (in this case text1,text2,text3)
        int[] to = new int[] {R.id.text1};

        // Now create a simple cursor adapter and set it to display
        SimpleCursorAdapter adapter = 
            new SimpleCursorAdapter(this, R.layout.cate_row, t, from, to);
        setListAdapter(adapter);
        }
@Override
protected void onListItemClick(ListView list, View v, int position, long id)
{
    super.onListItemClick(list, v, position, id);
    titleClick = (int) list.getPositionForView(v);
    final Intent intent = new Intent(this, inputpage.class);
    final MediaPlayer titleClickSound = MediaPlayer.create(this, R.raw.button50); 
    titleClickSound.start();
    startActivityForResult(intent, position);
    }
@Override
protected void onResume() {
    if (mydbhelper != null) {
        mydbhelper.open();};
    super.onResume();
}

@Override
protected void onPause() {
    mydbhelper.close();
    super.onPause();
}
//Menu Items
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.layout.menu, menu);
    return true;
}

public boolean onOptionsItemSelected(MenuItem item) {
    // Handle item selection
    switch (item.getItemId()) {
         case R.id.help:
           showHelp();
            return true;
       }
    return false;
}

    private void showHelp() {
        LayoutInflater inflater = (LayoutInflater)
                   this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                 pw = new PopupWindow(
                   inflater.inflate(R.layout.help, null, false), 
                   LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT, 
                   true);
                 pw.showAtLocation(this.findViewById(R.id.text1), Gravity.CENTER, 0, 0); 
    }
    public void onClickHelp(View helper){pw.dismiss();

    }
}   

这次尝试再次导致崩溃,它给了我一个不同的错误

03-06 21:52:40.250: E/Database(15818): Leak found
03-06 21:52:40.250: E/Database(15818): java.lang.IllegalStateException: /data/data/wanted.pro.madlibs/databases/madlib SQLiteDatabase created and never closed
03-06 21:52:40.250: E/Database(15818):  at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1695)
03-06 21:52:40.250: E/Database(15818):  at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:739)
03-06 21:52:40.250: E/Database(15818):  at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:761)
03-06 21:52:40.250: E/Database(15818):  at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:754)
03-06 21:52:40.250: E/Database(15818):  at android.app.ApplicationContext.openOrCreateDatabase(ApplicationContext.java:473)
03-06 21:52:40.250: E/Database(15818):  at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:193)
03-06 21:52:40.250: E/Database(15818):  at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:98)
03-06 21:52:40.250: E/Database(15818):  at wanted.pro.madlibs.dbadapter.open(dbadapter.java:176)
03-06 21:52:40.250: E/Database(15818):  at wanted.pro.madlibs.title.onCreate(title.java:29)
03-06 21:52:40.250: E/Database(15818):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
03-06 21:52:40.250: E/Database(15818):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2459)
03-06 21:52:40.250: E/Database(15818):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)
03-06 21:52:40.250: E/Database(15818):  at android.app.ActivityThread.access$2200(ActivityThread.java:119)
03-06 21:52:40.250: E/Database(15818):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863)
03-06 21:52:40.250: E/Database(15818):  at android.os.Handler.dispatchMessage(Handler.java:99)
03-06 21:52:40.250: E/Database(15818):  at android.os.Looper.loop(Looper.java:123)
03-06 21:52:40.250: E/Database(15818):  at android.app.ActivityThread.main(ActivityThread.java:4363)
03-06 21:52:40.250: E/Database(15818):  at java.lang.reflect.Method.invokeNative(Native Method)
03-06 21:52:40.250: E/Database(15818):  at java.lang.reflect.Method.invoke(Method.java:521)
03-06 21:52:40.250: E/Database(15818):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
03-06 21:52:40.250: E/Database(15818):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
03-06 21:52:40.250: E/Database(15818):  at dalvik.system.NativeStart.main(Native Method)

我一直试图阻止这种泄漏。以为我有它,但猜不是。想知道泄漏是否可能导致问题,因为onclick中的int用于dbhelperclass底部的游标

public class dbadapter extends SQLiteOpenHelper {

     //The Android's default system path of your application database.
   public static final String DB_PATH = "/data/data/wanted.pro.madlibs/databases/";
   public static final String DB_NAME = "madlib";
   public static final int DB_VERSION = 39;


   //database variables
   public static final String  KEY_ID = "_id";
   public static final String  KEY_CATEGORYDESC = "categorydesc";
   public static final String KEY_TITLE = "titlekey";
   public static final String KEY_TITLEDESC = "titledesc";
   public static final String KEY_TITLESTORY = "titlestory";
   public static final String KEY_SOURCEDESC = "sourcedesc";
   public static final String KEY_SOURCE = "sourcekey";
   public static final String KEY_CATEGORY = "categorykey";
   public static final String KEY_USERWORD = "userword";
   public static final String KEY_EDITWORD = "editword";
   public static final String KEY_QUICK = "quick";

   //table variables
   public static final String CATEGORY_TABLE = "category";
   public static final String SOURCE_TABLE = "source";
   public static final String TITLE_TABLE = "title";
   public static final String SOURCE_CATEGORY_TABLE = "source_category";
   public static final String SOURCE_TITLE_TABLE = "source_title";
   public static final String CATEGORY_TITLE_TABLE = "category_title";
   public static final String USER_WORD_TABLE = "userword";

   private dbadapter mydbhelper;
   public static SQLiteDatabase myDataBase; 

  /**
    * Constructor
    * Takes and keeps a reference of the passed context in order to access to the application assets and resources.
    * @param context
    */

       private final Context mCtx;
    public dbadapter(Context context) {
    super(context, DB_NAME, null, DB_VERSION);
       this.mCtx = context;
   }    

 /**
    * Creates a empty database on the system and rewrites it with your own database.
    * */
   public void createDataBase() throws IOException{
    boolean dbExist = checkDataBase();
    if(dbExist){
        Log.v("DB Exists", "db exists");
        this.getWritableDatabase();
        //do nothing - database already exist
    }
    dbExist=checkDataBase();
    if(!dbExist){
        //By calling this method and empty database will be created into the default system path
              //of your application so we are gonna be able to overwrite that database with our database.
        this.getReadableDatabase();

        try {
            copyDataBase();
        } catch (IOException e) {
            throw new Error("Error copying database");
        }
    }


   }

   /**
    * Check if the database already exist to avoid re-copying the file each time you open the application.
    * @return true if it exists, false if it doesn't
    */
   private boolean checkDataBase(){

    SQLiteDatabase checkDB = null;

    try{
        String myPath = DB_PATH + DB_NAME;
        checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);

    }catch(SQLiteException e){

        //database does't exist yet.

    }

    if(checkDB != null){

        checkDB.close();
    }

    return checkDB != null ? true : false;
   }

   /**
    * Copies your database from your local assets-folder to the just created empty database in the
    * system folder, from where it can be accessed and handled.
    * This is done by transferring bytestream.
    * */
   private void copyDataBase() throws IOException{

    //Open your local db as the input stream
    InputStream myInput = mCtx.getAssets().open(DB_NAME);

    // Path to the just created empty db
    String outFileName = DB_PATH + DB_NAME;

    //Open the empty db as the output stream
    OutputStream myOutput = new FileOutputStream(outFileName);

    //transfer bytes from the inputfile to the outputfile
    byte[] buffer = new byte[1024];
    int length;
    while ((length = myInput.read(buffer))>0){
        myOutput.write(buffer, 0, length);
    }

    //Close the streams
    myOutput.flush();
    myOutput.close();
    myInput.close();


   }

   public void openDataBase() throws SQLException{

    //Open the database
       String myPath = DB_PATH + DB_NAME;
        this.getWritableDatabase();
       myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);

   }

   @Override
    public synchronized void close() {

        if(myDataBase != null)
            myDataBase.close();

        super.close();

    }

    @Override
    public void onCreate(SQLiteDatabase db) {

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        if (newVersion > oldVersion)
        mCtx.deleteDatabase(DB_NAME);
        }

    public dbadapter open() throws SQLException {
        mydbhelper = new dbadapter (mCtx);
        myDataBase = mydbhelper.getWritableDatabase();
        return this;
    }


    // retrieves all the categories
      public Cursor getAllCategories() 
        {
            return myDataBase.query(CATEGORY_TABLE, new String[] {
                    KEY_ID, KEY_CATEGORY,
                    KEY_CATEGORYDESC,
                    }, 
                    null, null, null, null, KEY_CATEGORYDESC);

        }
    // retrieves all the titles
          public Cursor getTitles() 
            {
                return myDataBase.query(TITLE_TABLE, new String[] {
                        KEY_ID, 
                        KEY_TITLE,
                        KEY_TITLEDESC,
                        KEY_TITLESTORY, KEY_CATEGORY, KEY_SOURCE,
                        }, 
                        KEY_CATEGORY+ "=" + categories.categoryClick + " AND " + KEY_SOURCE+ "=" +source.sourceClick, null, null, null, KEY_TITLEDESC);

            }
        // retrieves all the descriptions for the edittext fields
          public  Cursor getUserWord() 
            {
                return myDataBase.query(USER_WORD_TABLE, new String[] {
                        KEY_ID, 
                        KEY_CATEGORY,
                        KEY_SOURCE, KEY_TITLE, KEY_USERWORD, KEY_QUICK 
                        }, 
                        KEY_CATEGORY+ "=" + categories.categoryClick + " AND " + KEY_SOURCE+ "=" 
                        +source.sourceClick + " AND " + KEY_TITLE+ "=" + title.titleClick, 
                        null, null, null, KEY_ID);

            }
            // Quick Start
          public Cursor getQuickStory() 
            {
                return myDataBase.query(TITLE_TABLE, new String[] {
                        KEY_ID, 
                        KEY_TITLE,
                        KEY_TITLEDESC,
                        KEY_TITLESTORY, KEY_CATEGORY, KEY_SOURCE,
                        }, 
                        KEY_ID+ "=" + main.RandomNum, null, null, null, null);

            }

          public  Cursor getQuickWord() 
            {
                return myDataBase.query(USER_WORD_TABLE, new String[] {
                        KEY_ID, 
                        KEY_CATEGORY,
                        KEY_SOURCE, KEY_TITLE, KEY_USERWORD, KEY_QUICK 
                        }, 
                        KEY_QUICK+ "=" + main.RandomNum, 
                        null, null, null, KEY_ID);

            }

          public Cursor getSource()
          {
             return myDataBase.query(SOURCE_TABLE, new String[]{
                    KEY_ID, KEY_SOURCEDESC, KEY_CATEGORY,},
                    KEY_CATEGORY+ "=" + categories.categoryClick, null, null, null, KEY_SOURCEDESC);
          } 

            // retrieves story to diplay in last activity
          public Cursor getStory() 
            {
                return myDataBase.query(TITLE_TABLE, new String[] {
                        KEY_ID, 
                        KEY_TITLE,
                        KEY_TITLEDESC,
                        KEY_TITLESTORY, KEY_CATEGORY, KEY_SOURCE,
                        }, 
                        KEY_CATEGORY+ "=" + categories.categoryClick + " AND " + KEY_SOURCE+ "=" +source.sourceClick + " AND " + KEY_TITLE+ "=" + title.titleClick, null, null, null, null);

            }


} 

1 个答案:

答案 0 :(得分:0)

我不确定这是否是您的异常的原因,但以下看起来可能会导致您遇到一些问题。你定义:

public static int titleClick;

然后在onListItemClick致电:

titleClick = (int) list.getPositionForView(v);

我假设正在从应用程序中的其他活动访问此公共静态变量。由于Android管理您的Activity的方式(请参阅流程图here),如果您的应用程序的进程已被终止然后重新启动,则此静态变量可能会变为空/未定义。如果在调用 onListItemClick之前访问,它也将为null。

此外,您应该可以使用position中的onListItemClick参数代替:(int) list.getPositionForView(v)