2015-08-28 5 views
1

У меня есть приложение, которое отлично работает. Мне пришлось обновить базу данных, которая привела к удалению базы данных и восстановлению базы данных. Я просто удалил базу данных. Однако я не могу его прочитать и перестроить новую базу данных. Журнал ошибок выглядит следующим образом:Приложение для Android сбой при копировании базы данных

08-28 13:03:33.932 32378-32378/com.bkane56.practice.practiceapp D/AndroidRuntime﹕ Shutting down VM 
08-28 13:03:33.933 32378-32378/com.bkane56.practice.practiceapp E/AndroidRuntime﹕ FATAL EXCEPTION: main 
    Process: com.bkane56.practice.practiceapp, PID: 32378 
    java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.bkane56.practice.practiceapp/com.bkane56.practice.practiceapp.ListStopsActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.sqlite.SQLiteDatabase android.content.Context.openOrCreateDatabase(java.lang.String, int, android.database.sqlite.SQLiteDatabase$CursorFactory, android.database.DatabaseErrorHandler)' on a null object reference 
      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2250) 
      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2413) 
      at android.app.ActivityThread.access$800(ActivityThread.java:155) 
      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1317) 
      at android.os.Handler.dispatchMessage(Handler.java:102) 
      at android.os.Looper.loop(Looper.java:135) 
      at android.app.ActivityThread.main(ActivityThread.java:5356) 
      at java.lang.reflect.Method.invoke(Native Method) 
      at java.lang.reflect.Method.invoke(Method.java:372) 
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905) 
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700) 
    Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.sqlite.SQLiteDatabase android.content.Context.openOrCreateDatabase(java.lang.String, int, android.database.sqlite.SQLiteDatabase$CursorFactory, android.database.DatabaseErrorHandler)' on a null object reference 
      at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:268) 
      at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:223) 
      at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:187) 
      at com.bkane56.practice.practiceapp.MetroLinkDatabaseHelper.createdatabase(MetroLinkDatabaseHelper.java:67) 
      at com.bkane56.practice.practiceapp.MetroLinkDatabaseHelper.<init>(MetroLinkDatabaseHelper.java:54) 
      at com.bkane56.practice.practiceapp.MetroLinkDatabaseHelper.getInstance(MetroLinkDatabaseHelper.java:40) 
      at com.bkane56.practice.practiceapp.ListStopsActivity.<init>(ListStopsActivity.java:27) 
      at java.lang.reflect.Constructor.newInstance(Native Method) 
      at java.lang.Class.newInstance(Class.java:1606) 
      at android.app.Instrumentation.newActivity(Instrumentation.java:1089) 
      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2240) 
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2413) 
            at android.app.ActivityThread.access$800(ActivityThread.java:155) 
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1317) 
            at android.os.Handler.dispatchMessage(Handler.java:102) 
            at android.os.Looper.loop(Looper.java:135) 
            at android.app.ActivityThread.main(ActivityThread.java:5356) 
            at java.lang.reflect.Method.invoke(Native Method) 
            at java.lang.reflect.Method.invoke(Method.java:372) 
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905) 
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700) 

Проблема возникает (сбой при отладке) в помощнике базы данных. Который выглядит следующим образом:

import android.content.Context; 
import android.database.Cursor; 
import android.database.sqlite.SQLiteDatabase; 
import android.database.sqlite.SQLiteException; 
import android.database.sqlite.SQLiteOpenHelper; 

import java.io.File; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.OutputStream; 
import java.text.ParseException; 
import java.text.SimpleDateFormat; 
import java.util.ArrayList; 
import java.util.List; 


public class MetroLinkDatabaseHelper extends SQLiteOpenHelper { 

    private Context mycontext; 
    private String stopName; 
    private String sqlQueryTimes; 
    private String sqlQueryDepart; 
    private static MetroLinkDatabaseHelper myInstance; 

    private static String DB_PATH = "data/data/com.bkane56.practice.practiceapp/databases/"; 
    private static String DB_NAME = "metrolink2.db"; 
    public static SQLiteDatabase myDataBase; 


    public static synchronized MetroLinkDatabaseHelper getInstance(Context context) { 

//  Using a singleton to minmize the chance of opening multiple 
//  decreasing any chance of memory leak 
     if(myInstance == null) { 
      myInstance = new MetroLinkDatabaseHelper(context); 
     } 
     return myInstance; 
    } 


    private MetroLinkDatabaseHelper(Context context) { 
     super(context, DB_NAME, null, 1); 
     this.mycontext = context; 
     boolean dbexist = checkdatabase(); 
     if (dbexist) { 
     } else { 
      System.out.println("Database doesn't exist"); 
      try { 
       createdatabase(); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    } 

    //  Create (copy the original in assets) if not exist using copydatabase 
    public void createdatabase() throws IOException { 
     boolean dbexist = checkdatabase(); 
     if (dbexist) { 
     } else { 
      this.getReadableDatabase(); 
      try { 
       copydatabase(); 
      } catch (IOException e) { 
       throw new Error("Error copying database"); 
      } 
     } 
    } 

    //  Check if the Android database has been created from attached database 
    private boolean checkdatabase() { 
     boolean checkdb = false; 
     try { 
      String myPath = DB_PATH + DB_NAME; 
      File dbfile = new File(myPath); 
      checkdb = dbfile.exists(); 
      if (!checkdb) { 
       System.out.println("THE DATA BASE DOES NOT EXIST"); 
      } 
     } catch (SQLiteException e) { 
      System.out.println("Database doesn't exist"); 
     } 

     return checkdb; 
    } 

    // copies the data from the metroLink db in assets to data/data....metrolink.db 
    public void copydatabase() throws IOException { 

     // Open your local db as the input stream 
     InputStream myinput = mycontext.getAssets().open(DB_NAME); 
     String outfilename = DB_PATH + DB_NAME; 

     // Open the empty db as the output stream 
     OutputStream myoutput = new FileOutputStream(outfilename); 

     // buffered reader to write new database 
     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 static SQLiteDatabase open() { 
     // Open the database 
     String mypath = DB_PATH + DB_NAME; 
     myDataBase = SQLiteDatabase.openDatabase(mypath, null, 
       SQLiteDatabase.OPEN_READONLY); 
     return myDataBase; 
    } 

    public synchronized void close() { 
     super.close(); 
     myDataBase.close(); 

    } 

    public void delete() { 
     //Delete Existing Database 
     File mypath = new File(DB_PATH + DB_NAME); 
     myDataBase.close(); 
     System.out.println("DELETING THE EXISTING DATABASE"); 
     myDataBase.deleteDatabase(mypath); 
    } 

Когда я отладка он получает в:

this.getReadableDatabase(); 

линии, а затем возвращается к GetInstance, а затем следующий шаг выходит из строя целиком.

Я не думаю, что это в listStopsActivity, но я буду включать это в любом случае:

package com.bkane56.practice.practiceapp; 

import android.app.Activity; 
import android.os.Bundle; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.view.View; 
import android.widget.ArrayAdapter; 
import android.widget.Button; 
import android.widget.ListView; 
import android.widget.RadioButton; 
import android.widget.RadioGroup; 
import android.widget.Spinner; 
import android.widget.TextClock; 
import android.widget.TextView; 

import java.text.SimpleDateFormat; 
import java.util.Arrays; 
import java.util.Calendar; 
import java.util.List; 


public class ListStopsActivity extends Activity { 

    private Spinner lvMetroStop; 
    private MetroLinkDatabaseHelper myHelper = 
      MetroLinkDatabaseHelper.getInstance(this); 
    private String routeColor; 
    private String direction; 
    private String stop; 
    private ListView stopTimes; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_list_stops); 

     populateStopsDb(); 

    } 

    private void openDB() { 

     myHelper.open(); 
    } 

    private void closeDB() { 
     myHelper.close(); 
    } 


    private void populateStopsDb() { 

     lvMetroStop = (Spinner) findViewById(R.id.metroStopList); 
     List<String> metroStop = myHelper.getAllStops(); 

     // Create ArrayAdapter using the planet list. 
     ArrayAdapter<String> listAdapter = new ArrayAdapter<>(this, R.layout.simplerow, metroStop); 
     lvMetroStop.setAdapter(listAdapter); 
    } 

    public void populateTimesDB() { 

     String dateTime = (new SimpleDateFormat("EEEE HH:mm:ss").format(Calendar.getInstance().getTime())); 
     String[] dayTime = dateTime.split(" "); 
     String weekDay = dayTime[0]; 
     String time = dayTime[1]; 

     String query = "SELECT st.arrival_time FROM routes r" + 
       " JOIN trips t on t.route_id = r.route_id JOIN calendar c on c.service_id =t.service_id" + 
       " JOIN stop_times st on st.trip_id = t.trip_id JOIN stops s on s.stop_id = st.stop_id" + 
       " WHERE r.route_id LIKE \"12594" + routeColor + "\" AND s.stop_name LIKE \"" + stop + 
       "\" AND t.direction_id = \"" + direction + "\" AND st.arrival_time >= \"" + time + 
       "\" AND c." + weekDay + " = 1 ORDER BY st.arrival_time LIMIT 3;"; 

     stopTimes = (ListView) findViewById(R.id.lvStopTimes); 
     List<String> metroStopTimes = myHelper.getStopTimes(query); 

     // Create ArrayAdapter using the planet list. 
     ArrayAdapter<String> listAdapter = new ArrayAdapter<>(this, 
       R.layout.stop_time, metroStopTimes); 
     stopTimes.setAdapter(listAdapter); 

    } 

    public void getStopName(View view) { 

     lvMetroStop = (Spinner) findViewById(R.id.metroStopList); 
     stopTimes = (ListView) findViewById(R.id.lvStopTimes); 
     TextView stopName = (TextView) findViewById(R.id.tvStopVar); 
     Button getStop = (Button) findViewById(R.id.btnGetTimest); 
     TextClock myClock = (TextClock) findViewById(R.id.textClock); 
     TextView thisStop = (TextView) findViewById(R.id.stop_time); 
     Button reset = (Button) findViewById(R.id.btnGetNew); 
     TextView header = (TextView) findViewById(R.id.open_stops_header); 
     RadioGroup eastWest = (RadioGroup) findViewById(R.id.rgEastWest); 
     RadioGroup redBule = (RadioGroup) findViewById(R.id.rgRedBlue); 
     TextView blueRed = (TextView) findViewById(R.id.tvRouteColor); 
     TextView westEast = (TextView) findViewById(R.id.tvDirection); 
     RadioButton red = (RadioButton) findViewById(R.id.rbRed); 
     RadioButton blue = (RadioButton) findViewById(R.id.rbBlue); 
     RadioButton east = (RadioButton) findViewById(R.id.rbEast); 
     RadioButton west = (RadioButton) findViewById(R.id.rbWest); 


     header.setText("The Next 3 Stop Times Are"); 

//  gets the text from the list view (spinner) 
     stop = lvMetroStop.getSelectedItem().toString(); 
     stopName.setText(stop); 

//  set Visibilities 
     stopTimes.setVisibility(View.VISIBLE); 
     reset.setVisibility(View.VISIBLE); 
     thisStop.setVisibility(View.VISIBLE); 
     stopName.setVisibility(View.VISIBLE); 
     myClock.setVisibility(View.VISIBLE); 
     lvMetroStop.setVisibility(View.INVISIBLE); 
     getStop.setVisibility(View.INVISIBLE); 
     eastWest.setVisibility(View.INVISIBLE); 
     redBule.setVisibility(View.INVISIBLE); 
     blueRed.setVisibility(View.INVISIBLE); 
     westEast.setVisibility(View.INVISIBLE); 
     header.setText("The Current Time Is:"); 


//  set East/West and Red/Blue 
     if (red.isChecked()) { 
      routeColor = "R"; 
     } else { 
      routeColor = "B"; 
     } 
     if (east.isChecked()) { 
      direction = "0"; 
     } else { 
      direction = "1"; 
     } 

     populateTimesDB(); 

    } 

    public void resetGetStopName(View view) { 

     TextView stopName = (TextView) findViewById(R.id.tvStopVar); 
     TextClock myClock = (TextClock) findViewById(R.id.textClock); 
     Button getStop = (Button) findViewById(R.id.btnGetTimest); 
     TextView thisStop = (TextView) findViewById(R.id.stop_time); 
     Button reset = (Button) findViewById(R.id.btnGetNew); 
     TextView header = (TextView) findViewById(R.id.open_stops_header); 
     RadioGroup eastWest = (RadioGroup) findViewById(R.id.rgEastWest); 
     RadioGroup redBule = (RadioGroup) findViewById(R.id.rgRedBlue); 
     TextView blueRed = (TextView) findViewById(R.id.tvRouteColor); 
     TextView westEast = (TextView) findViewById(R.id.tvDirection); 
     stopTimes = (ListView) findViewById(R.id.lvStopTimes); 

//  set the header text and change visibility 
     header.setText(R.string.open_list_of_stops); 
     lvMetroStop.setVisibility(View.VISIBLE); 
     getStop.setVisibility(View.VISIBLE); 
     eastWest.setVisibility(View.VISIBLE); 
     redBule.setVisibility(View.VISIBLE); 
     blueRed.setVisibility(View.VISIBLE); 
     westEast.setVisibility(View.VISIBLE); 
     stopName.setVisibility(View.INVISIBLE); 
     myClock.setVisibility(View.INVISIBLE); 
     reset.setVisibility(View.INVISIBLE); 
     thisStop.setVisibility(View.INVISIBLE); 
     stopTimes.setVisibility(View.INVISIBLE); 
     header.setText("Choose Your Station From List"); 

    } 

    private final String[] RED_STOPS = new String[]{ 
      "LAMBERT MAIN TRML METROLINK STATION", 
      "LAMBERT EAST TRML METROLINK STATION", 
      "NORTH HANLEY METROLINK STATION", 
      "UMSL NORTH METROLINK STATION", 
      "ROCK ROAD METROLINK STATION", 
      "WELLSTON METROLINK STATION", 
      "DELMAR METROLINK STATION", 
      "MEMORIAL HOSPITAL METROLINK STATION", 
      "SWANSEA METROLINK STATION", 
      "BELLEVILLE METROLINK STATION", 
      "COLLEGE METROLINK STATION", 
      "SHILOH-SCOTT METROLINK STATION"}; 

    private final String[] BLUE_STOPS = new String[]{ 
      "RICHMOND HEIGHTS METROLINK STATION", 
      "CLAYTON METROLINK STATION", 
      "BRENTWOOD METROLINK STATION", 
      "MAPLEWOOD METROLINK STATION", 
      "SUNNEN METROLINK STATION", 
      "SHREWSBURY METROLINK STATION", 
      "FORSYTH METROLINK STATION", 
      "UMSL SOUTH METROLINK STATION", 
      "SKINKER METROLINK STATION"}; 


    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.menu_list_stops, menu); 
     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     // Handle action bar item clicks here. The action bar will 
     // automatically handle clicks on the Home/Up button, so long 
     // as you specify a parent activity in AndroidManifest.xml. 
     int id = item.getItemId(); 

     //noinspection SimplifiableIfStatement 
     if (id == R.id.action_settings) { 
      return true; 
     } 

     return super.onOptionsItemSelected(item); 
    } 
} 

Любые предложения будут оценены.

EDIT: Sorry @Lal, я проверил другую ветку. Правильный номер строки 67:

this.getReadableDatabase(); 

Мои извинения.

+0

Что такое линия № 67 в MetroLinkDatabaseHelper.java? – Lal

+0

в методе createdatabase() ... Строка 67 = copydatabase(); – bkane56

+0

@ Lal ... извините, но я изменился на другую ветку. На самом деле строка: this.getReadableDatabase(); – bkane56

ответ

0

Благодаря @CommonsWare на другом посту я получил ответ. Я звонил в MetrolinkDatabaseHelper перед OnCreate деятельности в ListAllStops:

private MetroLinkDatabaseHelper myHelper = 
     MetroLinkDatabaseHelper.getInstance(this); 

Переменная нужно быть объявлена ​​как переменная класса и назначается после super.onCreate:

Спасибо @CommonsWare.

Смежные вопросы