2013-04-15 32 views
0

我的android/java代码有问题。当我从一个活动切换到另一个活动时,我简单地收到错误。我确定的问题是数据库。堆栈跟踪中的主要错误是活动空指针和未明确关闭的数据库。任何人都可以提供一些关于这个问题的帮助吗Java/Android活动与数据库关闭()问题

是否有人熟悉下面的错误跟踪?

事情是,我有2种方法可以到达我想要的页面。通过快捷方式,当我第一次加载应用程序时,下一个按钮给我错误。但是当我完成编辑时,进入我想要的页面然后回来。第一个'下一个'然后起作用。这太讨厌了!

这是logcat的轨迹:

FATAL EXCEPTION: main 
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.android.sec/com.android.sec.TabLayoutActivity}: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.android.sec/com.android.sec.RoomOverview}: java.lang.NullPointerException 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679) 
at android.app.ActivityThread.access$2300(ActivityThread.java:125) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033) 
at android.os.Handler.dispatchMessage(Handler.java:99) 
at android.os.Looper.loop(Looper.java:123) 
at android.app.ActivityThread.main(ActivityThread.java:4627) 
04-15 20:37:05.333: E/AndroidRuntime(568): at java.lang.reflect.Method.invokeNative(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:521) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 
at dalvik.system.NativeStart.main(Native Method) 
Caused by: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.android.sec/com.android.sec.RoomOverview}: java.lang.NullPointerException 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663) 
at android.app.ActivityThread.startActivityNow(ActivityThread.java:2503) 
at android.app.LocalActivityManager.moveToState(LocalActivityManager.java:127) 
at android.app.LocalActivityManager.startActivity(LocalActivityManager.java:339) 
at android.widget.TabHost$IntentContentStrategy.getContentView(TabHost.java:651) 
at android.widget.TabHost.setCurrentTab(TabHost.java:323) 
at android.widget.TabHost.addTab(TabHost.java:213) 
at com.android.sec.TabLayoutActivity.onCreate(TabLayoutActivity.java:30) 
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627) 
... 11 more 
E/AndroidRuntime(568): Caused by: java.lang.NullPointerException 
at com.android.sec.RoomOverview.onCreate(RoomOverview.java:106) 
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627) 
E/AndroidRuntime(568): ... 20 more 

这里是抛出错误类:你只需要确保使用后关闭游标和dbHelper对象

package com.android.sec; 

import java.util.ArrayList; 

import android.app.Activity; 
import android.app.AlertDialog; 
import android.content.Context; 
import android.content.DialogInterface; 
import android.content.Intent; 
import android.database.Cursor; 
import android.database.sqlite.SQLiteDatabase; 
import android.graphics.Color; 
import android.os.Bundle; 
import android.view.View; 
import android.widget.AdapterView; 
import android.widget.AdapterView.OnItemClickListener; 
import android.widget.ArrayAdapter; 
import android.widget.ImageButton; 
import android.widget.ListView; 
import android.widget.TextView; 

public class RoomOverview extends Activity { 

    public String value = CreateClient.getName(); 
    public String status = CreateRoom.getStatus(); 
    private ListView lvItem; 
    private ArrayList<String> itemArrey; 
    private ArrayAdapter<String> itemAdapter; 
    public Cursor c, c2, c3, c4, c5, c6; 
    SQLiteDatabase sampleDB; 
    public static String selectedItem; 
    ImageButton edit, delete; 
    final Context context = this; 
    public String typeToDelete; 
    public static String getID[]; 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.roomoverview); 

     edit = (ImageButton) findViewById(R.id.editButton); 
     edit.setEnabled(false); 
     edit.setAlpha(127); 

     delete = (ImageButton) findViewById(R.id.deleteButton); 
     delete.setEnabled(false); 
     delete.setAlpha(127); 

     lvItem = (ListView)this.findViewById(R.id.listView1); 
     lvItem.setTextFilterEnabled(true); 

     itemArrey = new ArrayList<String>(); 
     itemArrey.clear(); 

     itemAdapter = new ArrayAdapter<String>(getApplicationContext(), R.layout.single_item,itemArrey); 
     lvItem.setAdapter(itemAdapter); 

     if(value == "Retrieve"){ 

      sampleDB = getBaseContext().openOrCreateDatabase(ClientList.retrievedClient+".db", MODE_PRIVATE, null); 
     } 
     else if (value == "Create"){ 

      sampleDB = getBaseContext().openOrCreateDatabase(CreateClient.createdClient+".db", MODE_PRIVATE, null); 
     } 


     if(status == "Edit"){ 

      TextView roomName = (TextView) findViewById(R.id.roomName); 
      roomName.append(EditRoom.possiblyEditedRoom); 
      c = sampleDB.rawQuery("SELECT * FROM tbl_plant WHERE r_id =?", new String[] {RoomList.r_id}); 
      c2 = sampleDB.rawQuery("SELECT * FROM tbl_windowData WHERE r_id =?", new String[] {RoomList.r_id}); 
      c3 = sampleDB.rawQuery("SELECT * FROM tbl_itData WHERE r_id =?", new String[] {RoomList.r_id}); 
      c4 = sampleDB.rawQuery("SELECT * FROM tbl_otherData WHERE r_id =?", new String[] {RoomList.r_id}); 
      c5 = sampleDB.rawQuery("SELECT * FROM tbl_heatingData WHERE r_id =?", new String[] {RoomList.r_id});  
      c6 = sampleDB.rawQuery("SELECT * FROM tbl_lightingData WHERE r_id =?", new String[] {RoomList.r_id}); 
     } 
     else if (status == "Create"){ 

      TextView roomName = (TextView) findViewById(R.id.roomName); 
      roomName.append(CreateRoom.selectedRoom); 
      c = sampleDB.rawQuery("SELECT * FROM tbl_plant WHERE r_id =?", new String[] {CreateRoom.r_id}); 
      c2 = sampleDB.rawQuery("SELECT * FROM tbl_windowData WHERE r_id =?", new String[] {CreateRoom.r_id}); 
      c3 = sampleDB.rawQuery("SELECT * FROM tbl_itData WHERE r_id =?", new String[] {CreateRoom.r_id}); 
      c4 = sampleDB.rawQuery("SELECT * FROM tbl_otherData WHERE r_id =?", new String[] {CreateRoom.r_id});  
      c5 = sampleDB.rawQuery("SELECT * FROM tbl_heatingData WHERE r_id =?", new String[] {CreateRoom.r_id}); 
      c6 = sampleDB.rawQuery("SELECT * FROM tbl_lightingData WHERE r_id =?", new String[] {CreateRoom.r_id});  
     } 

     itemArrey.add("---------- Plant ----------"); 
     if (c != null) { 
      if (c.moveToFirst()) { 
       do { 

        String id = c.getString(c.getColumnIndex("p_id")); 
        String plantName = c.getString(c.getColumnIndex("itemName")); 
        String plantType = c.getString(c.getColumnIndex("itemType")); 
        itemArrey.add("Plant Name: "+plantName+"\n"+"Type: "+plantType+"\n"+"ID: #"+id); 

       }while (c.moveToNext()); 
      } 
     } 
     c.close(); 

Multiple of the above i.e. c2, c3, c4 etc. etc. - saves reading 

     lvItem.setOnItemClickListener(new OnItemClickListener() { 
      public void onItemClick(AdapterView<?> parent, View view, 
        int position, long id) { 
       // When clicked, show a toast with the TextView text 

       selectedItem = (String) ((TextView) view).getText(); 
       if(selectedItem.contains("----------")){} 

       else { 
        edit.setEnabled(true); 
        edit.setAlpha(255); 
        delete.setEnabled(true); 
        delete.setAlpha(255); 

       //Toast.makeText(getApplicationContext(), "item: "+selectedItem+" child: "+parent.getCount(), Toast.LENGTH_LONG).show(); 
       for(int a = 0; a < parent.getChildCount(); a++) 
       { 
        parent.getChildAt(a).setBackgroundColor(Color.WHITE); 
       } 

       view.setBackgroundColor(Color.parseColor("#97C361")); 

       } 
      } 
     }); 

     edit.setOnClickListener(new View.OnClickListener() { 
      public void onClick(View view) { 

       if(selectedItem.contains("----------")){} 

       else { 

       sampleDB.close(); 

       if(selectedItem.startsWith("Plant Name:")){ 
        typeToDelete = "P"; 
       } 
       else if (selectedItem.startsWith("Type:")){ 
        typeToDelete = "W"; 
       } 
       else if (selectedItem.startsWith("PC Quantity:")){ 
        typeToDelete = "I"; 
       } 
       else if (selectedItem.startsWith("Other Name:")){ 
        typeToDelete = "O"; 
       } 
       else if (selectedItem.startsWith("Heating Type:")){ 
        typeToDelete = "H"; 
       } 
       else if (selectedItem.startsWith("Lighting Type:")){ 
        typeToDelete = "L"; 
       } 

       getID = selectedItem.split("#"); 

       if(typeToDelete == "P"){ 

        Intent intent2 = new Intent(RoomOverview.this, EditPlant.class); 
        startActivityForResult(intent2, 0); 

       } 
       else if (typeToDelete == "W"){ 

        Intent intent2 = new Intent(RoomOverview.this, EditWindows.class); 
        startActivityForResult(intent2, 0); 

       } 
       else if (typeToDelete == "I"){ 

        Intent intent2 = new Intent(RoomOverview.this, EditIT.class); 
        startActivityForResult(intent2, 0); 

       } 
       else if (typeToDelete == "O"){ 

        Intent intent2 = new Intent(RoomOverview.this, EditOther.class); 
        startActivityForResult(intent2, 0); 

       } 
       else if (typeToDelete == "H"){ 

        Intent intent2 = new Intent(RoomOverview.this, EditHeating.class); 
        startActivityForResult(intent2, 0); 

       } 
       else if (typeToDelete == "L"){ 

        Intent intent2 = new Intent(RoomOverview.this, EditLighting.class); 
        startActivityForResult(intent2, 0); 

        } 
       } 
      } 
     }); 

     delete.setOnClickListener(new View.OnClickListener() { 
      public void onClick(View view) { 

       if(selectedItem.contains("----------")){} 

       else { 

       AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context); 
       alertDialogBuilder.setTitle("Delete:"); 

       alertDialogBuilder.setMessage("Are you sure?").setCancelable(false).setPositiveButton("Yes",new DialogInterface.OnClickListener() { 
        public void onClick(DialogInterface dialog,int id) { 
         //delete building 

         if(selectedItem.startsWith("Plant Name:")){ 
          typeToDelete = "P"; 
         } 
         else if (selectedItem.startsWith("Type:")){ 
          typeToDelete = "W"; 
         } 
         else if (selectedItem.startsWith("PC Quantity:")){ 
          typeToDelete = "I"; 
         } 
         else if (selectedItem.startsWith("Other Name:")){ 
          typeToDelete = "O"; 
         } 
         else if (selectedItem.startsWith("Heating Type:")){ 
          typeToDelete = "H"; 
         } 
         else if (selectedItem.startsWith("Lighting Type:")){ 
          typeToDelete = "L"; 
         } 

         String getID[] = selectedItem.split("#"); 

         if(typeToDelete == "P"){ 
          sampleDB.delete("tbl_plant", "p_id =?", new String[] {getID[1]}); 
         } 
         else if (typeToDelete == "W"){ 
          sampleDB.delete("tbl_windowData", "w_id =?", new String[] {getID[1]}); 
         } 
         else if (typeToDelete == "I"){ 
          sampleDB.delete("tbl_itData", "i_id =?", new String[] {getID[1]}); 
         } 
         else if (typeToDelete == "O"){ 
          sampleDB.delete("tbl_otherData", "o_id =?", new String[] {getID[1]}); 
         } 
         else if (typeToDelete == "H"){ 
          sampleDB.delete("tbl_heatingData", "h_id =?", new String[] {getID[1]}); 
         } 
         else if (typeToDelete == "L"){ 
          sampleDB.delete("tbl_lightingData", "l_id =?", new String[] {getID[1]}); 
         } 

         sampleDB.close(); 

         Intent intent2 = new Intent(RoomOverview.this, TabLayoutActivity.class); 
         startActivityForResult(intent2, 0);  
      } 
     }) 
     .setNegativeButton("No",new DialogInterface.OnClickListener() { 
        public void onClick(DialogInterface dialog,int id) { 
         //do nothing 
         dialog.cancel(); 
        } 
       }); 

       AlertDialog alertDialog = alertDialogBuilder.create(); 
       alertDialog.show(); 
      } 
      }});  
    } 
} 

回答

2

首先不使用的...

if (value == "Retrieve") { ... 

if (value == "Create") { ... 

if (status == "Edit") { ... 

...因为这并不在Java中工作。使用...

if ("Retrieve".equals(value)) { ... 

if ("Create".equals(value)) { ... 

if ("Edit".equals(status)) { ... 

...改为。因此,您的光标c很可能是null。如果您已将c.close()置于您的if声明之内,那么这不会成为问题。因此,其次将您close()方法调用if语句中:

if (c != null) { 
    if (c.moveToFirst()) { 
     do { 
      ... 

     } while (c.moveToNext()); 
    } 
    c.close(); // move to here 
} 
// here, close() is outside of the if causing a NPE if c is null 

甚至,如果可能不会解决所有问题 - 这至少是一个开始,我希望它能帮助;)

干杯!

+0

非常有帮助,我接管了一些家伙代码,对这个问题进行了逆向工程。非常感谢! – cwiggo

+1

欢迎您。关闭实际为“空”的游标变量以及未关闭的游标(通常是由于监控条件造成的)在许多情况下是数据库问题的根本原因。 – Trinimon

+0

对,对此表示感谢! – cwiggo

1

。 即cursor.close()或dbHelper.close()...等。

另外,我建议您使用扩展SQLiteOpenHelper的类。然后你可以使用该助手得到的引用一个SQLiteDatabase,

SQLiteDatabase db = dbHelper.getWritableDatabase(); 
//db.query(....) 
//db.select(....) 
etc... 

有吨关于这个教程。

+0

我已经确定使用cursor.close()关闭了每个游标,但我仍然在跟踪中看到了这个错误消息!它可能会这样说的任何其他原因? – cwiggo

+0

很难说没有看到您的代码 – Tom

+0

看到主要问题,我已经添加了源代码frmo有问题的类 – cwiggo

1

异常来自第106行,试图关闭一个空的游标。无论是放置支票,还是移动呼叫以关闭光标进入前面的(c!= null)检查。

+0

所以你不必关闭游标,如果它是空的? – cwiggo

+2

那实际上并不是重点。那恰好是异常被提出的地方。您应该尝试管理资源并在不再需要时释放它们。如果仅在活动之间切换时发生此异常,则是因为您的活动状态未得到正确管理。例如,在切换回您的活动时,不保证字段“值”和“状态”保留。切换活动时最好保存状态。在Android.com上查看此链接,http://developer.android.com/training/basics/activity-lifecycle/stopping.html。 –

+0

是的,有人推荐给我,它有多难实施? – cwiggo