Reputation: 21
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
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
Reputation: 276
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
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