无法实例化应用程序java.lang.RuntimeException:... BackupDB无法强制转换为android.app.Application

时间:2014-02-12 18:18:39

标签: java android android-intent

MANIFEST :(局部视图)   MainActivity,程序立即终止并在日志中发出消息。   它应该已经开始显示按钮以选择继续执行的选项。   经过几天研究这个论坛,我发现帖子建议将BackupDb放在Manifest中的应用程序中。   在这之后,我最终得到了日志中的消息   在我的研究场地耗尽之后,我想知道可能是什么问题以及如何解决它。

MANIFEST :(部分观点)

  <?xml version="1.0" encoding="utf-8"?>
  <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.peter.databasetest"
  android:versionCode="1"
  android:versionName="1.0" >

  <uses-sdk
  android:minSdkVersion="16"
  android:targetSdkVersion="19" />

  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

  <supports-screens
  android:xlargeScreens="true"
  android:largeScreens="true"
  android:normalScreens="true"
  android:smallScreens="false"
  />

  <application
  android:allowBackup="true"
  android:icon="@drawable/ic_launcher"
  android:label="@string/app_name"
  android:theme="@style/AppTheme" 
  **android:name="com.peter.databasetest.BackupDB">**

  <activity
  android:name="com.peter.databasetest.MainActivity"
  android:label="@string/app_name" >
  <intent-filter>
  <action android:name="android.intent.action.MAIN" />
  <category android:name="android.intent.category.LAUNCHER" />
  </intent-filter>
  </activity>
  <activity
  android:name=".CheckDatabase"
  android:label="@string/app_name" >
  <intent-filter>
  <action android:name="android.intent.action.CHECKDATABASE" />
  <category android:name="android.intent.category.DEFAULT" />
  </intent-filter>
  </activity>  

  <activity
  android:name=".CheckSDcard"
  android:label="@string/app_name" >
  <intent-filter>
  <action android:name="android.intent.action.CHECKSDCARD" />
  <category android:name="android.intent.category.DEFAULT" />
  </intent-filter>
  </activity>  

  <activity
  android:name="com.peter.databasetest.Insert"
  android:label="@string/app_name" >
  <intent-filter>
  <action android:name="com.peter.databasetest.INSERT" />
  <category android:name="android.intent.category.DEFAULT" />
  </intent-filter>
  </activity>
  </application>
   </manifest>

MainActivity:调用checkSDcard和CheckDatabase。检查是否存在SDCard并且数据库是否存在。

  public class MainActivity extends Activity implements OnClickListener {


    DBAdapter db;
    Button insertButton;                      //ADD A NEW RECORD
    Button listAllButton;                      //LIST ALL 
    Button cancelButton;                     //CANCEL PGM
    Button  backupDbButton;          //REQUEST BACKUP DB TO SDCARD
    Button restoreButton;                   //RESTORE DB FROM SDCARD TO MAIN
    Button memsizeButton;               //SHOW MEMORY SIZES ON  DEVICE

    int retcode;
    int chk;
    String message;
    public Context context;
    public  static final  String NO_DB ="Database does not exist. Backup is not possible";
    public  static final  String DB_PB ="ERROR- Check log";
    public  static final  String UNWR_SDCARD ="Your SDCard must be set to writable. Check the card lock";
    public  static final  String NO_SDCARD ="No SDcard detected. No backup is possible";
    public  static final  String BKP_OK = "Backup was SUCCESSFUL.";
    public  static final  String BKP_NOK = "Backup FAILED. "; 
                static final     int SD_CHECK = 1; 
                static final     int DB_CHECK = 2; 
                static final     int BK_CHECK = 3; 

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

        insertButton            = (Button) findViewById(R.id.insertButton);
        listAllButton               = (Button) findViewById(R.id.listAllButton);
        cancelButton            = (Button) findViewById(R.id.cancelButton);
         backupDbButton     = (Button) findViewById(R.id.backupDbButton);
         restoreButton          = (Button) findViewById(R.id.restoreButton);
         memsizeButton            = (Button) findViewById(R.id. memsizeButton);


        insertButton.setOnClickListener(this);              //insert record  into DB
        listAllButton.setOnClickListener(this);             //list ALL records from DB
        cancelButton.setOnClickListener(this);              //cancel the program
        backupDbButton.setOnClickListener(this);        //request backup to sdcard
        restoreButton.setOnClickListener(this);            //request restore from sdcard
        memsizeButton.setOnClickListener(this);        //Get Meory sizes


    public void onClick(View v ) {

        if (v  == insertButton) {
            startActivity(new Intent(getApplicationContext(), Insert.class));

        }else if (v  == listAllButton){
                    startActivity (new Intent(MainActivity.this, ListDr.class)); 

        }else if (v  == backupDbButton){             
            **Intent checksd = new Intent(this,CheckSDcard.class);**
            **startActivityForResult(checksd,  SD_CHECK);**              

        }else if (v ==  restoreButton) {
                    startActivity (new Intent(MainActivity.this,RestoreDB.class));

        }else if (v ==  memsizeButton) {
                startActivity (new Intent(MainActivity.this,GetMemorySizes.class));

         }else if (v  == cancelButton){   
                 finish();
                } 
       }  
     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);

            if (requestCode == SD_CHECK && resultCode == RESULT_OK) {

                    Intent checkdb = new Intent(MainActivity.this,CheckDatabase.class);
                    startActivityForResult(checkdb,  DB_CHECK);              

            }else if (requestCode == DB_CHECK && resultCode == RESULT_OK){

                    **Intent backup = new Intent(MainActivity.this,BackupDB.class);**
                    **startActivityForResult(backup, BK_CHECK);**       

            }else if (requestCode == BK_CHECK && resultCode == RESULT_OK){
                    message = BKP_OK;
                    SendMessageDialog(message);
                    finish();
            } 
                if(resultCode == RESULT_CANCELED && resultCode == -1){ 
                    message = NO_DB;                                                     
                    SendMessageDialog(message); 
                    finish();

                }else if(resultCode == RESULT_CANCELED && resultCode == -2) { 
                    message = DB_PB;                                                 
                    SendMessageDialog(message); 
                    finish();
                } 
            }

BackupDb:将数据库复制到SDCARD。

  package com.peter.databasetest;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import com.peter.databasetest.DBAdapter;

public  class BackupDB extends  AsyncTask<Void, Void, Integer> { 

    DBAdapter db;
    intrc= -10;
    intretcode;
    intchk;
    Stringmessage;
    String mypackage;
    public Context context; 
    public static  String FOLDER_NAME = "DBfolder";
    public  static  final  String DATABASE_NAME = "UserDB.db";
    public  static  final  String DATABASE_BACKUP= "UserDB.db";
    public  static final  String BKP_OK = "Backup was SUCCESSFUL.";
    public  static final  String BKP_NOK = "Backup FAILED. ";

    @Override 
    protected void onPreExecute() {
    //  GET PACKAGE NAME
    mypackage = context.getApplicationContext().getPackageName() ;
    }
    //     START BACKUP TO SDCARD

    @Override
    protected Integer doInBackground(Void... params) {

    //    DOING BACKUP

    Log.i("00000" , "STARTING BACKUP...BACKUP ");
    File sd = Environment.getExternalStorageDirectory();  
    File data = Environment.getDataDirectory(); 

    CREATE A FOLDER   /mnt/sdcard<packagename>FOLDER_NAME if it does not exist  

    File folder = new File(Environment.getExternalStorageDirectory()   
    + "/"
    + mypackage 
    + "/" 
    + FOLDER_NAME);
    if(!folder.exists()) {
    if (folder.mkdirs()) ;
    }                                   

    // GET THE PATH OF THE BACKUP ON THE SDCARD

    FilefileBackupDir = new File(Environment.getExternalStorageDirectory() 
    + "/"
    +mypackage 
    + "/"
    + FOLDER_NAME
    +"/"
    + DATABASE_BACKUP) ;

    // IF WE HAVE A BACKUP ON SDCARD, DELETE IT TO MAKE ROOM FOR THE NEW  BACKUP

    if (fileBackupDir.exists()) {
    fileBackupDir.delete(); 
    }else { 
    * DO NOTHING */
    } 
    //   GET CURRENT DB PATH FOR THE COPY         
    String currentDBPath = "/data/" + mypackage  + "/databases/"+ DATABASE_NAME;         
    //   GET CURRENT DB PATH FOR THE BACKUP          
    String backupDBPath =  "/" + mypackage  + "/"  +FOLDER_NAME + "/" + DATABASE_BACKUP; 

    FilecurrDB  = new File(data,  currentDBPath)  ;         
    FilebkpDB   = new File(sd,  backupDBPath);

    FileChannel from = null;
    try {
    from = new FileInputStream(currDB).getChannel();
    } catch (FileNotFoundException e) {
    e.printStackTrace();
    }
    FileChannel to = null;
    try {
    to = new FileOutputStream(bkpDB).getChannel();
    } catch (FileNotFoundException e) {
    e.printStackTrace();
    }   
    try {
    to.transferFrom(from, 0, from.size());
    } catch (IOException e) {
    e.printStackTrace();
    }   
    try {
    from.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
    try {
    to.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
    retcode = 0;

    returnretcode;          
    //  end DoInBackgroung

    protectedvoid onPostExecute(Integer retcode, String message) {
    if(retcode == 0) {
    message = BKP_OK;
    SendMessageDialog(message);
    }else {
    message = BKP_NOK;
    SendMessageDialog(message);
    }
    }  
    public  void SendMessageDialog(String message) {
    if  (message == BKP_OK ) {   
    AlertDialog.Builder builder = new AlertDialog.Builder(context); 
    builder.setTitle("My Database")
    .setMessage(message)      // Title of the dialog 
    .setCancelable(true)     // Does  allow the use of Back Button on the hardware
    .setIcon(R.drawable.ecg)//  da picture
    .setPositiveButton("OK", new DialogInterface.OnClickListener() {
    public  void  onClick(DialogInterface dialog, int id) { 
    dialog.dismiss();
    dialog.cancel(); 
    }                 
    });
    final AlertDialog alert = builder.create(); 
    alert.show();        
    }else {
    AlertDialog.Builder builder = new AlertDialog.Builder(context);

    builder.setTitle("My Database")
    .setMessage(message)      // Title of the dialog 
    .setCancelable(true)     // Does  allow the use of Back Button on the hardware
    .setIcon(R.drawable.bad)//  da picture
    .setPositiveButton("OK", new DialogInterface.OnClickListener() {
    public  void  onClick(DialogInterface dialog, int id) { 
    dialog.dismiss();
    dialog.cancel(); 
    }                 
    });
    final AlertDialog alert = builder.create();
    alert.show();
    }
    }
    }

Logcat:

  02-12 07:36:06.015: E/AndroidRuntime(987): FATAL EXCEPTION: main
  02-12 07:36:06.015: E/AndroidRuntime(987): java.lang.RuntimeException: Unable to instantiate application com.peter.databasetest.BackupDB:     
  : com.peter.databasetest.BackupDB cannot be cast to  android.app.Application
  02-12 07:36:06.015: E/AndroidRuntime(987):    at android.app.LoadedApk.makeApplication(LoadedApk.java:501)
  02-12 07:36:06.015: E/AndroidRuntime(987):    at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4124)
  02-12 07:36:06.015: E/AndroidRuntime(987):    at android.app.ActivityThread.access$1300(ActivityThread.java:130)
  02-12 07:36:06.015: E/AndroidRuntime(987):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1255)
  02-12 07:36:06.015: E/AndroidRuntime(987):    at android.os.Handler.dispatchMessage(Handler.java:99)
  02-12 07:36:06.015: E/AndroidRuntime(987):    at android.os.Looper.loop(Looper.java:137)
  02-12 07:36:06.015: E/AndroidRuntime(987):    at android.app.ActivityThread.main(ActivityThread.java:4745)
  02-12 07:36:06.015: E/AndroidRuntime(987):    at java.lang.reflect.Method.invokeNative(Native Method)
  02-12 07:36:06.015: E/AndroidRuntime(987):    at java.lang.reflect.Method.invoke(Method.java:511)
  02-12 07:36:06.015: E/AndroidRuntime(987):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
  02-12 07:36:06.015: E/AndroidRuntime(987):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
  02-12 07:36:06.015: E/AndroidRuntime(987):    at dalvik.system.NativeStart.main(Native Method)
  02-12 07:36:06.015: E/AndroidRuntime(987): Caused by: java.lang.ClassCastException: com.peter.databasetest.BackupDB cannot be cast to android.app.Application
  02-12 07:36:06.015: E/AndroidRuntime(987):    at android.app.Instrumentation.newApplication(Instrumentation.java:982)
  02-12 07:36:06.015: E/AndroidRuntime(987):    at android.app.Instrumentation.newApplication(Instrumentation.java:967)
  02-12 07:36:06.015: E/AndroidRuntime(987):    at android.app.LoadedApk.makeApplication(LoadedApk.java:496)
  02-12 07:36:06.015: E/AndroidRuntime(987):    ... 11 more

注释:  我从应用程序中删除了BackupDb并将其恢复为活动。

<activity
android:name=".BackupDB"
android:label="@string/app_name" >
<intent-filter>
<action  android:name="com.peter.databasetest.BACKUPDB" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>  

程序现在按预期显示按钮,但在尝试备份时,我仍然会收到与早期日志相同的消息。 (捉住22?)

最新的日志:

  02-12 13:00:16.569: W/dalvikvm(30656): threadid=1: thread exiting with uncaught exception (group=0x40a13300)
  02-12 13:00:16.650: E/AndroidRuntime(30656): FATAL EXCEPTION: main
  02-12 13:00:16.650: E/AndroidRuntime(30656): java.lang.RuntimeException: Unable to instantiate activity      ComponentInfo{com.peter.databasetest/com.peter.databasetest.BackupDB}: java.lang.ClassCastException: com.peter.databasetest.BackupDB cannot be cast to android.app.Activity
  02-12 13:00:16.650: E/AndroidRuntime(30656):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1983)
  02-12 13:00:16.650: E/AndroidRuntime(30656):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
  02-12 13:00:16.650: E/AndroidRuntime(30656):  at android.app.ActivityThread.access$600(ActivityThread.java:130)
  02-12 13:00:16.650: E/AndroidRuntime(30656):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
  02-12 13:00:16.650: E/AndroidRuntime(30656):  at android.os.Handler.dispatchMessage(Handler.java:99)
  02-12 13:00:16.650: E/AndroidRuntime(30656):  at android.os.Looper.loop(Looper.java:137)
  02-12 13:00:16.650: E/AndroidRuntime(30656):  at android.app.ActivityThread.main(ActivityThread.java:4745)
  02-12 13:00:16.650: E/AndroidRuntime(30656):  at java.lang.reflect.Method.invokeNative(Native Method)
  02-12 13:00:16.650: E/AndroidRuntime(30656):  at java.lang.reflect.Method.invoke(Method.java:511)
  02-12 13:00:16.650: E/AndroidRuntime(30656):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
  02-12 13:00:16.650: E/AndroidRuntime(30656):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
  02-12 13:00:16.650: E/AndroidRuntime(30656):  at dalvik.system.NativeStart.main(Native Method)
  02-12 13:00:16.650: E/AndroidRuntime(30656): Caused by: java.lang.ClassCastException: com.peter.databasetest.BackupDB cannot be cast to android.app.Activity
  02-12 13:00:16.650: E/AndroidRuntime(30656):  at android.app.Instrumentation.newActivity(Instrumentation.java:1053)
  02-12 13:00:16.650: E/AndroidRuntime(30656):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1974)
  02-12 13:00:16.650: E/AndroidRuntime(30656):  ... 11 more




>Question:
>Is there any known limitation calling an AsyncTask by way of startActivityForResult? 
>Could this be a factor?        

1 个答案:

答案 0 :(得分:4)

问题出在Manifest文件中,您正在设置应用程序:name为te BackupDB类,此类只是AsyncTask而不是Application。

可以在“android:name”的解释中看到:

  

实现整体的类的可选名称   这个包的android.app.Application。 [字符串]