huskydusky
huskydusky

Reputation: 21

Unable to instantiate activity cannot be cast to android.app.Activity

On trying to execute an Asynctask backup routine that's being called from another class I'm getting the message "Unable to instantiate activity cannot be cast to android.app.Activity." The compile goes OK, but the execution fails. I did a research on Intent and just can't find my way out. It is important to me to know what is going on, as I plan to make other classes call Asynctasks during the life of the application. Please let me know if more data is needed. The source codes are fairly large and I see no point in dumping eventual useless info. I would rather send what would be relevant to the issue.
Thank You

First call:

public class MainActivity extends Activity implements OnClickListener {

 } else if (v  == backupDbButton){ 
  startActivity (new Intent(this, CheckSDDB.class));

Second call:

public class CheckSDDB   extends Activity { 

     Intent intent = new Intent(CheckSDDB.this,RunBackup.class); 
     startActivity(intent);

Last Component:

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

Log:

02-21 15:14:15.067: E/AndroidRuntime(18123): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.peter.databasetest/com.peter.databasetest.RunBackup}: java.lang.ClassCastException:    com.peter.databasetest.RunBackup cannot be cast to android.app.Activity    02-21 15:14:15.067: E/AndroidRuntime(18123):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1983)
02-21 15:14:15.067: E/AndroidRuntime(18123):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
02-21 15:14:15.067: E/AndroidRuntime(18123):    at android.app.ActivityThread.access$600(ActivityThread.java:130)
02-21 15:14:15.067: E/AndroidRuntime(18123):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
02-21 15:14:15.067: E/AndroidRuntime(18123):    at android.os.Handler.dispatchMessage(Handler.java:99)
02-21 15:14:15.067: E/AndroidRuntime(18123):    at android.os.Looper.loop(Looper.java:137)
02-21 15:14:15.067: E/AndroidRuntime(18123):    at android.app.ActivityThread.main(ActivityThread.java:4745)
02-21 15:14:15.067: E/AndroidRuntime(18123):    at java.lang.reflect.Method.invokeNative(Native Method)
02-21 15:14:15.067: E/AndroidRuntime(18123):    at java.lang.reflect.Method.invoke(Method.java:511)
02-21 15:14:15.067: E/AndroidRuntime(18123):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
02-21 15:14:15.067: E/AndroidRuntime(18123):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
02-21 15:14:15.067: E/AndroidRuntime(18123):    at dalvik.system.NativeStart.main(Native Method)
02-21 15:14:15.067: E/AndroidRuntime(18123): Caused by: java.lang.ClassCastException: com.peter.databasetest.RunBackup cannot be cast to android.app.Activity
02-21 15:14:15.067: E/AndroidRuntime(18123):    at android.app.Instrumentation.newActivity(Instrumentation.java:1053)
02-21 15:14:15.067: E/AndroidRuntime(18123):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1974)
02-21 15:14:15.067: E/AndroidRuntime(18123):    ... 11 more

Manifest (partial)


<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=".RunBackup"
android:label="@string/app_name" >
<intent-filter>
<action  android:name="com.peter.databasetest.RUNBACKUP" />

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

@mike yaworski: I changed the line from (this, CheckSDDB.class). I didn't see any change in the execution. Thanks for the suggestion anyway.

@DuZi By removing the Runbackup from the Manifest I get this. Please see log below.

02-24 07:39:43.745: E/AndroidRuntime(5069): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.peter.databasetest/com.peter.databasetest.CheckSDDB}: android.content.ActivityNotFoundException: Unable to find explicit activity class {com.peter.databasetest/com.peter.databasetest.RunBackup}; have you declared this activity in your AndroidManifest.xml?
02-24 07:39:43.745: E/AndroidRuntime(5069):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
02-24 07:39:43.745: E/AndroidRuntime(5069):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
02-24 07:39:43.745: E/AndroidRuntime(5069):     at android.app.ActivityThread.access$600(ActivityThread.java:130)
02-24 07:39:43.745: E/AndroidRuntime(5069):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
02-24 07:39:43.745: E/AndroidRuntime(5069):     at android.os.Handler.dispatchMessage(Handler.java:99)
02-24 07:39:43.745: E/AndroidRuntime(5069):     at android.os.Looper.loop(Looper.java:137)
02-24 07:39:43.745: E/AndroidRuntime(5069):     at android.app.ActivityThread.main(ActivityThread.java:4745)
02-24 07:39:43.745: E/AndroidRuntime(5069):     at java.lang.reflect.Method.invokeNative(Native Method)
02-24 07:39:43.745: E/AndroidRuntime(5069):     at java.lang.reflect.Method.invoke(Method.java:511)
02-24 07:39:43.745: E/AndroidRuntime(5069):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
02-24 07:39:43.745: E/AndroidRuntime(5069):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
02-24 07:39:43.745: E/AndroidRuntime(5069):     at dalvik.system.NativeStart.main(Native Method)
02-24 07:39:43.745: E/AndroidRuntime(5069): Caused by: android.content.ActivityNotFoundException: Unable to find explicit activity class {com.peter.databasetest/com.peter.databasetest.RunBackup}; have you declared this activity in your AndroidManifest.xml?
02-24 07:39:43.745: E/AndroidRuntime(5069):     at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1541)
02-24 07:39:43.745: E/AndroidRuntime(5069):     at android.app.Instrumentation.execStartActivity(Instrumentation.java:1416)
02-24 07:39:43.745: E/AndroidRuntime(5069):     at android.app.Activity.startActivityForResult(Activity.java:3351)
02-24 07:39:43.745: E/AndroidRuntime(5069):     at android.app.Activity.startActivityForResult(Activity.java:3312)
02-24 07:39:43.745: E/AndroidRuntime(5069):     at android.app.Activity.startActivity(Activity.java:3522)
02-24 07:39:43.745: E/AndroidRuntime(5069):     at android.app.Activity.startActivity(Activity.java:3490)
02-24 07:39:43.745: E/AndroidRuntime(5069):     at com.peter.databasetest.CheckSDDB.onCreate(CheckSDDB.java:134)
02-24 07:39:43.745: E/AndroidRuntime(5069):     at android.app.Activity.performCreate(Activity.java:5008)
02-24 07:39:43.745: E/AndroidRuntime(5069):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
02-24 07:39:43.745: E/AndroidRuntime(5069):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2    023)
02-24 07:39:43.745: E/AndroidRuntime(5069):     ... 11 more

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

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

<activity
android:name=".ListDr"
android:label="@string/app_name" >
<intent-filter>
<action android:name="com.peter.databasetest.LISTDR" />

<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</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> 

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

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

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

</application>
 </manifest>

@Atul O Holic: RunBackup simply copies the database (data/data/...) to and SDcard. CheckSDDB checks for the existence of SDcard whether or not is writable, test for the existence of a main database to copy from and also checks if the database is empty (table is empty). Once the OK conditions are met in CheckSDDB, the startActyivity to RunBackup is called. RunBackup simply copies the DB to the SDCard (that's why I need Asynctask) and then returns to MainActivity. Since I'm still learning Java I'm not sure in which Activity onCreate I should place the Asynctask.
Here's the code for the RunBackup:

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.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Environment;
import android.util.Log;




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


        int  bkcode;     
        String message;
        public Context context;
           protected Dialog alert; 

        public static  String  PACKAGE_NAME ;
        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 TABLE_NAME = "tableone";
        public  static  final  int  DB_BACKUP_VERSION= 1;
          //CHECKING DATABASE RELATED MESSAGES dbcode

        public  static final  String NO_DB ="Database does not exist. Backup is not possible";
        public  static final  String EMPTY_DB ="Database is empty.\nNo backup was done.";
        public  static final  String UNKN_ERR ="Unknown Error.\nNo backup was done.";
                                    //CHECKING SDCARD RELATED MESSAGES  sdcode
        //////////////////////////////////////////////////////////////////////////////////////////////
        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";
        ///////////////////////////////////////////////////////////////////////////////////////////////
        //                                  BACKUP RELATED MESSAGES  bkcode
        //////////////////////////////////////////////////////////////////////////////////////////////
        public  static final  String BKP_OK = "Backup was SUCCESSFUL.- CheckSDDB";                                                        // 00
        public  static final  String FROM_FILE_NFOUND = "Input File not found. Backup not done";                              //-15
        public  static final  String TO_FILE_NFOUND = "Output File not found. Backup not done";                              //-14
        public  static final  String TO_FROM_COPY = "Problems Copying Input File to Output. Backup not done";    //-13
        public  static final  String FROM_INPUT = "Problems Closing the Input File. Backup not done";                        //-12
        public  static final  String TO_OUTPUT = "Problems closing the Output File. Backup not done";                    //-11
        public  static final   String BKP_NOK = "Backup FAILED. ";

        public  static final  String    TAG = "runBackup";

     protected void onPreExecute() {

    PACKAGE_NAME = context.getApplicationContext().getPackageName() ;
    }
         //////////////////////////////////////////////////////
         //             START BACKUP TO SDCARD
         //////////////////////////////////////////////////////
    @Override
    protected Integer doInBackground(Void... params) {
        bkcode = 0;  
    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()   
                                                + "/"
                                                + PACKAGE_NAME 
                                                + "/" 
                                                + FOLDER_NAME);

    if(!folder.exists()) {
    if (folder.mkdirs()) ;
    }                                   
    //////////////////////////////////////////////////////////////////////////
    //          GET THE PATH OF THE BACKUP ON THE SDCARD
   //////////////////////////////////////////////////////////////////////////
   File fileBackupDir = new File(Environment.getExternalStorageDirectory() 
                                                + "/"
                                                +PACKAGE_NAME 
                                                + "/"
                                                + 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.  THIS LOGIC KILLS ME... */
   } 
    /////////////////////////////////////////////////////////////
         //     GET CURRENT DB PATH FOR THE COPY
        /////////////////////////////////////////////////////////////
   String currentDBPath = "/data/" + PACKAGE_NAME  + "/databases/"+ DATABASE_NAME;         
        //   GET CURRENT DB PATH FOR THE BACKUP          
        String backupDBPath =  "/" + PACKAGE_NAME  + "/"  +FOLDER_NAME + "/" + DATABASE_BACKUP; 

   File currDB  = new File(data,  currentDBPath)  ;         
   File bkpDB   = new File(sd,  backupDBPath);

   FileChannel from = null;

   try {
   from = new FileInputStream(currDB).getChannel();
         } catch (FileNotFoundException e) {
            bkcode = -15;
            message = FROM_FILE_NFOUND ;
            SendMessageDialog(message);
        }
        FileChannel to = null;
         try {
            to = new FileOutputStream(bkpDB).getChannel();
               } catch (FileNotFoundException e) {
            bkcode = -14; 
             message = TO_FILE_NFOUND;
            SendMessageDialog(message);
         }   
  try {

            to.transferFrom(from, 0, from.size());
         } catch (IOException e) {
             bkcode = -13;
            message = TO_FROM_COPY ;
            SendMessageDialog(message);
                }   
         try {
            from.close();
         } catch (IOException e) {
            bkcode = -12; 
            message = FROM_INPUT;
            SendMessageDialog(message);
         }
         try {
            to.close();  
         } catch (IOException e) {  
            bkcode = -11; 
            message =  TO_OUTPUT;
            SendMessageDialog(message);
             }
         return bkcode;
         }
        protected void onPostExecute(Integer retcode, String message) {

   if(retcode == 0) {
                    message = BKP_OK;
                    SendMessageDialog(message);

                }else {
                    message = BKP_NOK;
                    SendMessageDialog(message);
                    }
        }
   ///////////////////////////////////////////////////////////////////
   //                       DISPLAY MESSAGES
   //////////////////////////////////////////////////////////////////
            public void SendMessageDialog(String message) {

                AlertDialog.Builder builder = new AlertDialog.Builder(context);
                if ( bkcode == 0) {
                    builder.setIcon(R.drawable.ecg);                        /* SET OK ICON */
                }else {
                    builder.setIcon(R.drawable.bad);    
                }
                    builder.setTitle("My MESSAGE")
                    .setMessage(message)                             // Title of the dialog 
                    .setCancelable(true)                                // allow the use of Back Button on the hardware 
                    .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                        public void  onClick(DialogInterface dialog, int id) {  
                            returnMain();
   }                  
            );
                    alert = builder.create(); 
                    alert.show();       
   }            

            ///////////////////////////////////////////////////////////////////
            //             BACK TO THE CALLING ACTIVITY
            ///////////////////////////////////////////////////////////////////
            public void returnMain() {
                if (alert != null   && alert.isShowing() ) { 
                    alert.dismiss();
                }
                Context ctx = context.getApplicationContext();
                Intent intent = new Intent(ctx, MainActivity.class);
                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                ctx.startActivity(intent);

            }
}   

@NPE: Thanks for the link. I already went through the explanation many times but I still fail to see why the RunBackup can't run as per the log above based on the explanation given at the link.

Upvotes: 1

Views: 3915

Answers (3)

Atul O Holic
Atul O Holic

Reputation: 6792

The issue is with the below line,

Intent intent = new Intent(CheckSDDB.this,RunBackup.class);

RunBackup is a subclass of an Asynctask and your intent is expecting an Activity. Hence the exceptions. Hence, as @NPE said create a new Activity which you call by doing,

Intent intent = new Intent(CheckSDDB.this,NewActivty.class);
startActivity(intent);

and place you Asynctask call in its onCreate() method. So that as soon as Activity is created your RunBackUp will be triggered.

And if you can also explain what you are looking to do with your Asynctask, that will make it easy for us to help.

Upvotes: 0

An intent is an abstract description of an operation to be performed. It can be used with startActivity to launch an Activity, broadcastIntent to send it to any interested BroadcastReceiver components, and startService(Intent) or bindService(Intent, ServiceConnection, int) to communicate with a background Service.

If you want to start RunBackup with an Intent then you need to extend Activity class or any of it's subclasses.

More info here.

Upvotes: 0

Michael Yaworski
Michael Yaworski

Reputation: 13483

This is not the entire solution (not sure what the problem with RunBackup is), but this may be something worth noting.

} else if (v  == backupDbButton){ 
    startActivity (new Intent(this, CheckSDDB.class));

I'm assuming this is called in onClick or some other method where v is the View. The problem with that is that this refers to that View (as far as I'm aware).

Try changing this:

startActivity (new Intent(this, CheckSDDB.class));

To this:

startActivity (new Intent(MainActivity.this, CheckSDDB.class));

Upvotes: 1

Related Questions