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

标签 java android android-intent

list :(部分 View ) MainActivity,程序立即终止并在日志中发出消息。 它应该已经开始显示按钮来选择继续执行的选项。 经过几天的研究这个论坛,我发现一些帖子建议将 BackupDb 放置在应用程序的 list 中。 完成此操作后,我最终在日志中看到了该消息。
在耗尽了我的研究空间后,我想知道可能存在什么问题以及如何解决它。

list :(部分 View )

  <?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 以及 main 中的数据库是否存在。

  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();
    }
    }
    }

日志猫:

  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 。

<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>  

程序现在按预期显示按钮,但在尝试备份时,我仍然收到与之前日志中相同的消息。 (第二十二条军规?)

最新日志:

  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?        

最佳答案

问题出在 Manifest 文件中,您将 application:name 设置为 BackupDB 类,并且该类只是一个 AsyncTask 而不是 Application。

从“android:name”的解释可以看出:

An optional name of a class implementing the overall
android.app.Application for this package. [string]

关于java - 无法实例化应用程序 java.lang.RuntimeException :. ..BackupDB 无法转换为 android.app.Application,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21736298/

相关文章:

android - 大胆的 ClickableSpan 触摸

java - 单击 ToggleButton 并调用函数时,Android 项目崩溃

java - if-else 优化和陷阱?

java - Spring Batch - 基于字段值的多个编写器

android - 如何 ACCESS_FINE_LOCATION 保持 GPS 关闭?

android-intent - 电子邮件意图未将 Exchange Mail (Outlook) 显示为选项

Android Intent to Gmail 不通过 FileProvider 附加文​​件 "Unable to attach file"

android - 发送电子邮件 Intent 选择器

java - Java 中的 HTML 解析

java - 为什么我应该在 public static void main(String[] args) 上抛出异常?