I have 2 activities in my app, in the second one I have the code to run when the "about" android action bar icon is clicked. In the first activity I have the same action bar menu items and I want to call this "about" method again, however when I click that, I have null Pointer exception. Anyone help ?
this is the method defined in the second activity - JokeDetailsActivity
public void aboutMe(){
AlertDialog.Builder dialog = new AlertDialog.Builder(JokeDetailsActivity.this);
dialog.setTitle("About");
dialog.setMessage("Hello! I'm ..., the creator of this application."
+"If there is any bug found please freely e-mail me. "+
"\n ...."
);
dialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
dialog.show();
}
when I call it in the first activity
case R.id.action_about:
JokeDetailsActivity jd = new JokeDetailsActivity();
jd.aboutMe();
return true;
}
thats the error I'm getting
09-12 20:11:42.748: E/AndroidRuntime(1032): FATAL EXCEPTION: main
09-12 20:11:42.748: E/AndroidRuntime(1032): java.lang.NullPointerException
09-12 20:11:42.748: E/AndroidRuntime(1032): at android.content.ContextWrapper.getApplicationInfo(ContextWrapper.java:140)
09-12 20:11:42.748: E/AndroidRuntime(1032): at android.view.ContextThemeWrapper.getTheme(ContextThemeWrapper.java:103)
09-12 20:11:42.748: E/AndroidRuntime(1032): at android.app.AlertDialog.resolveDialogTheme(AlertDialog.java:143)
09-12 20:11:42.748: E/AndroidRuntime(1032): at android.app.AlertDialog$Builder.<init>(AlertDialog.java:360)
09-12 20:11:42.748: E/AndroidRuntime(1032): at ie.myjokes.JokeDetailsActivity.aboutMe(JokeDetailsActivity.java:293)
09-12 20:11:42.748: E/AndroidRuntime(1032): at ie.myjokes.CategoryActivity.onOptionsItemSelected(CategoryActivity.java:140)
09-12 20:11:42.748: E/AndroidRuntime(1032): at android.app.Activity.onMenuItemSelected(Activity.java:2548)
No, don't do this
JokeDetailsActivity jd = new JokeDetailsActivity();
You are getting the error in the following line because you don't have the correct Context.
AlertDialog.Builder dialog = new AlertDialog.Builder(JokeDetailsActivity.this);
You are trying to call it in one Activity but use the Context of another Activity
You have a few options
1 Simply recreate this function in your other Activity and just
call it in that Activity with the proper Context (ActivityName.this)
2 Create a separate class that all of these Activities can call to use this function and pass the proper Context to that class.
3 Put this method in a BaseActivity and have your Activities extend this BaseActivity and place the method there.
I remembered #4
You could also create a separate Activity, like AboutActivity, to handle/show whatever you want and give it a Dialog Theme by adding the following line to the <activity tag in your manifest
android:theme="#android:style/Theme.Dialog"
then you just start that Activity from wherever you need.
What is this
JokeDetailsActivity jd = new JokeDetailsActivity();
jd.aboutMe();
If you want to start Activity you should do this using intent
You should never instantiate Activities
Create a seperate Class pass Context and create your aboutMe() method there and then reuse it
OR
Alternatively you can create it as static method in it
public static void aboutMe(Context mContext){
AlertDialog.Builder dialog = new AlertDialog.Builder(mContext);
dialog.setTitle("About");
dialog.setMessage("Hello! I'm ..., the creator of this application."
+"If there is any bug found please freely e-mail me. "+
"\n ...."
);
dialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
dialog.show();
}
then use it like
JokeDetailsActivity.aboutMe(getApplicationContext());
Yea that's it you start an Activity like:
Intent intent = new Intent(this, YourActivity.class);
startActivity(intent);
You cannot instantiate an Activity class like that and use it. The Activity creation is handled by Android system and it will need to get things like Context and stuff (which is the thing that you dont have, and you do use when you, for example, instantiate the AltertDialog builder, hence the null pointer exception). I would suggest that you make that method aboutMe a static method, and pass in a Context object to it:
public static void aboutMe(Context context){
AlertDialog.Builder dialog = new AlertDialog.Builder(context);
dialog.setTitle("About");
dialog.setMessage("Hello! I'm ..., the creator of this application."
+"If there is any bug found please freely e-mail me. "+
"\n ...."
);
dialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
dialog.show();
}
Declare that method as static and call it as JokeDetailsActivity.aboutMe(yourActivityContext). Don't create an object of activity and remember to pass the context, which you can then use to create the dialog. #Hi-Tech KitKat Android has givn more detailed answer.
Related
I'm very new to Android, and have a basic question. I need at certain points to display a user notification in a dialog box, which they can simply acknowledge with the OK button.
I'm using:
myActivity.runOnUiThread(new Runnable() {
public void run() {
AlertDialog alertDialog = new AlertDialog.Builder(myContext).create();
alertDialog.setTitle("Alert");
alertDialog.setMessage("My message");
alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
alertDialog.show();
}
});
This works well in the Main program, but within a called method it needs the Activity and the Context from the main program. Can anybody tell me how to pass these? getApplicationContext() seems to be acceptable, but I can't figure out how to pass the Activity.
Better still of course would be to get the parent Context and Activity within the method, but I can't get that to work either.
I'd be grateful for any help.
-update 10/07/21
Rahul has given me the solution to the problem I posed: how to pass in the Activity and Context.
The problem is that the dialog still doesn't show.
I found a variation online as follows:
AlertDialog.Builder builder = new AlertDialog.Builder(myContext);
builder.setTitle("Alert")
.setMessage("My message")
.setCancelable(false)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
AlertDialog alert = builder.create();
alert.show();
but this doesn't work either.
I'm puzzled that such a common and simple task needs so much code. In the desktop languages I'm used to it can be done in a single line.
So my titled question stands, but can anyone see where the code is faulty?
Many thanks
You can either pass activity to the class when initializing the object or you can pass activity when calling the function.
Case 1 (Recommended)
Pass Activity when calling the function:
MyObj myObj = new MyObj();
myObj.showDialog(myValue, ActivityName.this);
Where function will look like this:
public void showDialog(int myValue, Activity activity){
...
}
Then you can use this activity instance inside the method.
Case 2
Pass Activity when initializing the object:
MyObj myObj = new MyObj(ActivityName.this);
Where Class will look like this:
class MyObj{
private Activity thisActivity;
public MyObj(Activity activity){
thisActivity = Activity;
}
...
}
Then you can use this activity instance.
When you have activity object available you can replace context object with it.
In MainActivity, Context and MainActivity are different?
They are exactly getApplicationContext() and MainActivity.this in Method.
The reason I'm asking this is because i got error because of them.
if these are different, Complier didn't display red line in code.
I thought it was the same until now.
I got this error code.
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.writeweight, PID: 24595
java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.
at androidx.appcompat.app.AppCompatDelegateImpl.createSubDecor(AppCompatDelegateImpl.java:843)
at androidx.appcompat.app.AppCompatDelegateImpl.ensureSubDecor(AppCompatDelegateImpl.java:806)
at androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:693)
at androidx.appcompat.app.AppCompatDialog.setContentView(AppCompatDialog.java:95)
at androidx.appcompat.app.AlertController.installContent(AlertController.java:232)
at androidx.appcompat.app.AlertDialog.onCreate(AlertDialog.java:279)
at android.app.Dialog.dispatchOnCreate(Dialog.java:702)
at android.app.Dialog.show(Dialog.java:424)
at com.example.writeweight.MainActivity.onOptionsItemSelected(MainActivity.java:85)
at android.app.Activity.onMenuItemSelected(Activity.java:4182)
And I changed from getApplicationContext() to MainActivity.this and it worked well.
Code
MainActivity.class
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this); // HERE
builder.setTitle("SET");
builder.setPositiveButton("YES", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(getApplicationContext(),"TEST", Toast.LENGTH_SHORT).show();
}
});
AlertDialog dialog = builder.create();
dialog.show();
return true;
}
Tell me please.
Thank you
getApplicationContext() (somewhat unsurprisingly) returns the application context, whilst MainActivity.this is itself an activity context. Themes associated with your activity will differ from your application. They aren't the same thing.
if these are different, Complier didn't display red line in code.
You wont see an error, because it's only a Context that is requested. I haven't tried it, but you probably could use an Application instance so long as you specify the theme as well by using new AlertDialog.Builder(getApplicationContext(), /* theme res id */)
However, all the examples in the Android documentation use an Activity context, so I'd suggest you just go with that.
I am trying to access/call a method I have in my Activity from my class but I am getting null pointer exception when doing so.
Here's the method i am trying to call. This method is in my Activity:
public void start(Context context){
mHelper = new IabHelper(context.getApplicationContext(), base64EncodedPublicKey);
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
public void onIabSetupFinished(IabResult result) {
if (!result.isSuccess()) {
Log.d(TAG, "In-app Billing setup failed: " + result);
} else {
Log.d(TAG, "In-app Billing is set up OK");
mHelper.enableDebugLogging(true, TAG);
startPurchase();
}
}
});
}
In my class where I am calling it from, I have made an instance of the class:
ThemeActivity themeact = new ThemeActivity();
And I am trying to call it from an onClicklistener within my class:
new AlertDialog.Builder(getContext())
.setMessage(
"Would you like to purchase this theme?")
.setCancelable(false)
.setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
public void onClick(
DialogInterface dialog, int id) {
//Here is where I am calling it
themeact.start(getContext());
}
}).setNegativeButton("No", null).show();
And I receive the following error in LogCat:
FATAL EXCEPTION: main
java.lang.NullPointerException
at android.content.ContextWrapper.getApplicationContext(ContextWrapper.java:109)
at test.test.util.IabHelper.<init>(IabHelper.java:164)
at test.test.ThemeActivity.start(ThemeActivity.java:161)
at test.test.ColorCard$1$1.onClick(ColorCard.java:67)
at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:171)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:213)
at android.app.ActivityThread.main(ActivityThread.java:5225)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:741)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
at dalvik.system.NativeStart.main(Native Method)
EDIT
I realized that I was calling the wrong method to start with, and now i am calling the correct method and it still crashes with a null pointer exception with a different error. I have tried to pass a context and it still isn't working. Whenever I try to call the method start(); from the on create of my Activity, it works. But then when trying to call the exact same method from my other class it crashes and I have no idea why. I initialize everything from within the method itself so I'm not sure why it crashes with null.
Try passing the context variable of the activity as an argument to startPurchase() method
In the end I fixed my problem by moving my class inside my activity class. I am not sure why it works now but it didn't when I had the class I was using as a separate class.
I have a dialogfragment that I use for the user to input information into. when the user clicks ok the info is passed back to the main activity through an interface where I attempt to put it into a database.
this is the dialog positive click code:
.setPositiveButton("Ok", new DialogInterface.OnclickListener(){
#Override
public void onClick(DialogInterface dialog, int which){
name = edittextname.getText().toString();
details = edittextdetails.getText().toString();
bundle.putString("name", name);
bundle.putString("detail", detail);
mListener.OnAddInfo(Bundle);
and on the mainactivity I implemented the interface and this in code:
public void OnAddInfo(Bundle bundle){
name = bundle.getString("name");
detail = bundle.getString("detail");
db.open();
long id = db.insertInfo(name, detail);
db.close();
Toast.makeText(this, "Added " + name, Toast.LENGTH_SHORT).show();
}
I know the data is being passed through because when I comment out the db parts the toast comes up correctly. I don't think there is a problem with my db because in other activities not using a dialogfragment it works fine. The error msg i get is this:
FATAL EXCEPTION: main
java.lang.NullPointerException at
android.database.sqlite.SQLiteOpenHelper
.getDatabaseLocked(SQLiteOpenHelper.java:224)
I have tried many things to fix this and just cant figure it out. Is this just something that isnt allowed or am I just missing something? The mainactivity is also a fragmentactivity.
I spent hours on this and gave up, only to accidentally discover a solution. Declaring the new database at the beginning of the DialogFragment class where you usually declare stuff doesn't work, but declaring it inside the onCreateDialog method works!
Example:
onCreateDialog(){
DatabaseHandler db = new DatabaseHandler(getActivity());
// use db now with no lock.
}
I am developing an Android app, this app has a dozen of Activities, each one is for a corresponding screen. Now I have this common subtitle bar on top of the screens.
this subtitle bar has a button to display an alert dialog which shows link list to go to a different screen.
I could write a same function for each activity to call the alert dialog, but that would be tedious if I want to modify them, so I created this class:
public class MenuAlertDialog extends Activity {
/*
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
}
*/
public void createMenu(final Context context){
AlertDialog.Builder dlg = new AlertDialog.Builder(context);
dlg.setTitle("menu");
String[] items = {"pageA", "pageB", "pageC", "pageD", "pageE"};
dlg.setItems(items, new DialogInterface.OnClickListener(){
#Override
public void onClick(DialogInterface dialog, int which){
switch(which){
case 0:
Intent intent = new Intent(context, MainActivity.class);
startActivity(intent);
break;
default:
break;
}
}
});
dlg.show();
}
}
and call it from each activity, like this:
MenuAlertDialog menu = new MenuAlertDialog();
menu.createMenu(this);
from inside of onCreate.
It can display the alertDialog, but whenever I press pageA link, it fails with an unexpected error.
Logcat says its a nullpointererror and the cause seems
startActivity(intent);
What am I doing wrong?
Remove the code
extends Activity
as you have no need to extend your class that you are creating since it does not rely on any activity related functionality.
Where you call startActivity(intent); replace it with
context.startActivity(intent);
You should change the class to Extends Dialog and not activity.
Also for Try this:
Check out this tutorial on how to create a custom dialog. Custom Dialog
Also Here Another Tutorial
And Here