I'd like to make some text via Toast inside message handler, and my message handler is declared in the separate class.
public class HandlerAlert extends Handler {
final static byte IP_OK=0;
final static byte IP_WRONG=-1;
Context ctx;
public HandlerAlert(Context ctx) {
super();
this.ctx=ctx;
}
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case IP_OK:
if (msg.arg1==(CheckSendMode.REGULAR).ordinal())
{
Toast.makeText(ctx/*null*/,
"OK",Toast.LENGTH_LONG).show();
Log.i("MessageOk",ctx.getClass().getName());
}
........
I have two activities, and both can call this message. I expected that my Toast.MakeText would produce output in the activity which context (parameter ctx) is used. However, I see the output in both activities despite of ctx passed. Name of activity passed in Context ctx is observed by Log.i("MessageOk",ctx.getClass().getName()); I thought that Toast.MakeText works in all activities despite of context, and even tested null context (absolutely expected exception was obtained).
My question is the following: does Toast.MakeText send output in the activity which is currently open? I'm ready to provide any part of code if necessary.
Thanks in advance.
Create a class ShowToast
inside that class create a method
public Class ShowToast{
Context mContext;
public void displayToast(String msg){
Toast.makeText(mContext,msg,Toast.LENGTH_LONG).show();
}
Inside your activity
ShowToast dispToast = new ShowToast(this);
btn.setOnClickListener(new View.OnClickListener(){
publiv void onClick(View v){
dispToast.showToast("Hello World");
}
});
It is hypothesis only: I suppose that in fact toastuses application context, not activity one. I try
Toast.makeText(ctx.getApplicationContext(), "OK",Toast.LENGTH_LONG).show();
and it works as if it would be activity context. By the way,
Log.i("MessageOk",ctx.getApplicationContext().getClass().getName());
produces class android.app.Application. Please confirm or deny my supposition.
Related
I'm following tutorials on how to put functions that are used frequently in activities all in one place.
For example, a toast message that comes up throughout my project, instead of having the function in each and every activity, just having it called in one place, GlobalFunctions.java.
So, I get it with simple functions, for example, in GlobalFunctions.java :
public class GlobalFunctions {
public void simpleMessage() {
System.out.println("simpleMessage text goes here");
}
}
And the I call it like this from Activity1:
GlobalFunctions simplemessage = new GlobalFunctions();
simplemessage.simpleMessage();
But what about? :
public class GlobalFunctions {
public void simpleMessage() {
Toast.makeText(getApplicationContext(), "simpleMessage text goes here", Toast.LENGTH_LONG).show();
}
}
I've looked at several posts including getApplicationContext() error Android and no matter what I put in the Context part of Toast I get a Cannot resolve method message. Also if there's any good tutorials for Dummies on this subject I'd be grateful.
The key is static .
Static values allow you to use static methods variables ..etc in whole project.
You can use following concept:
public static class GlobalFunctions {
public static void simpleMessage(Context context, String message) {
Toast.makeText(context, message, Toast.LENGTH_LONG).show();
}
}
And you have to invoke it like:
GlobalFunctions.simpleMessage(/*YourActivity.this*/ /*or*/ /*getActivity()*/, "toast");
One solution would be to pass the Context as a parameter from the Activity or Fragment.
And instead of instantiating GlobalFunctions, writing and using static methods can be a better approach.
Create a Java Utils class:
public class Utils {
public static void showToast(Context context, String text) {
Toast.makeText(context, text, Toast.LENGTH_LONG).show();
}
}
// for example on the Activity code
Utils.showToast(this, "This is the toast text");
Keeping context in field beyond activity can be reason of memory leak, but there is some workaround.
You can create Singleton with application or application context and initialize it in onCreate in your custom application class. But you have to remember that you can't use this context to build views - it is not stylized.
Other way is just pass context as argument.
Sorry for missing code, response from phone :)
try this Create class like this to pass Context and Toast message as parameter like this
public class GlobalFunctions {
public static void simpleMessage(Context context,String message) {
Toast.makeText(Context, message, Toast.LENGTH_LONG).show();
}
}
call this function like this
GlobalFunctions.simpleMessage(YourActivity.this,"your Mesaage");
As I'm really annoyed of passing the Context for most of the operations in Android (Database, Toast, Preferences). I was wondering if it's a good way of programming to initialize these elements once (e.g. in Application-Class).
It works quite good, I don't have to pass the element from Class to class and I can't see any disadvantages. Thats the reason why I wanted to ask you guys. Why shouldn't I use this?
For the people who don't know what I mean:
MainApplication:
public class MainApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
VolleySingleton.init(this);
Toaster.init(this);
PrefUtilities.init(this);
}
}
Toaster:
public class Toaster {
private static Toaster mInstance = null;
private Context context;
private Toast currentToast;
private Toaster(Context context) {
this.context = context;
}
public static void init(Context context) {
mInstance = new Toaster(context);
}
public static void toast(String message){
if (mInstance.currentToast != null){
mInstance.currentToast.cancel();
}
mInstance.currentToast = Toast.makeText(mInstance.context, message, Toast.LENGTH_SHORT);
mInstance.currentToast.show();
}
}
I'm also interested in the question, why the context for Toast or other stuff is needed? I can use the application context for the Toast and have access in every single Activity / Fragment. Why has the Android-Team implemented it this way?
So basically two questions:
1. Do I have any disadvantages with my implementation (memory, time) ?
2. Why do classes like Toast require a context at all?
1. Do I have any disadvantages with my implementation (memory, time) ?
Well, you are always initiating your db, even if you dont use it at all during that session, same goes for the other classes. Couldnt think of anything else, since you would use application context anyways, at least for database.
2. Why do classes like Toast require a context at all?
Toast requires a context since it touches the UiThread, so it needs a reference to access the thread.
I have an app that uses custom Exceptions, such as this:
public class SomeException extends Exception{
private int iCode;
private String iMessage;
public SomeException(){
iCode = 201;
iMessage = **//Get the localized string R.string.error_201??**
}
#Override
public String getMessage() {
return iMessage;
}
#Override
public int getCode() {
return iCode;
}
}
Obviously, I want lo localize the error message. I have possible solutions but non of them satisfy me.
1) Pass "Context" to the constructor, and do ctx.getString(R.string.error_201)
--> Fail, as this Exceptions are sometimes thrown from MODEL classes, so they don't have a Context
2) Pass "Context" when retriveing the message in getMessage() function,
--> Fail, It's necesary to override the super method, to work as all other Exceptions.
Solution I have now: All activities in my app have this onCreate:
public void onCreate(...){
Utils.RESOURCES = getResources();
...
}
Very dirty code... I don't like the solution. My question is then,: is there a way to access the resources without the Context? And most important, How would an application such as mine solve this problem?
What about
public class MyException extends Exception {
private int iCode;
public MyException(int code) {
this.iCode = code;
}
#Override
public String getMessage() {
return "MyException code " + String.valueOf(iCode);
}
public String getLocalizedMessage(Context ctx) {
String message;
if (iCode == 201)
message = ctx.getString(R.string.error_201);
else if (iCode == 202)
message = ctx.getString(R.string.error_202);
// ...
}
}
Even if there was way to access context in different way, you should not do it. If you need to emit exceptions where you cannot pass Context, you should be able to access context before you display such error. I cannot see reason why you should create localized error messages from constructor. You can log to logcat not localized versions if you need. And where you want to display something in UI, you should have context at hand.
You can access only system wide resources without Context.
You need a Context, so I would suggest You to get it as soon as possible, and make it available through a static method or variable. You do the same thing in every Activity, but there is a cleaner method. You should make a custom Application, and override its onCreate() to make the resources public:
public class App extends Application {
private static Resources myResources;
#Override
public void onCreate() {
myResources = getBaseContext().getResources();
super.onCreate();
}
public static Resources getMyResources(){
return myResources;
}
}
The other thing you have to do is to set the Application in your manifest:
<application
android:name="{your_package}.App"
...
Now you can access the resources in all of your Activity without any preparation. Your custom Exception class could also use the externalized resources.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do I make a toast from a non activity class?
How can I create and show a Toast message from a class which does not extended the Activity class? I'm using this class in another class that is extended by Activity.
You need a context Reference. Just have a helper method like
public static void showToastMethod(Context context) {
Toast.makeText(context, "mymessage ", Toast.LENGTH_SHORT).show();
}
---------------------- New Modular Version ------------------------
Create an Interface
public interface ShowToast {
public onShowToast (String message); [additionally you can pass toast duration]
}
In Activity class, implement this interface and write Toast method to show message.
public class ActivityClass extends Activity implements ShowToast{
public giveCallToNonActivityClass(){
new NonActivityClass(this); //Here we're passing interface impl reference.
}
public onShowToast (String message) {
Toast.makeText(ActivityClass.this, message, Toast.LENGTH_SHORT).show();
}
}
Sample NonActivityClass will look like:
public class NonActivityClass {
public NonActivityClass (ShowToast interfaceImpl) {
interfaceImpl.onShowToast("I'm calling Toast from Non Activity ");
}
}
Earlier version was too old to refer. Hope this more modular approach help.
-------------------------------- Old Version 2012 ----------------------------
You can pass context of that activity to your class by passing value to nonActivity class
example:
new NonActivityClass(Activityclass.this) ;
and as in above answer
new MyClass(ActivityClass.this);
In NonActivityClass
public class NonActivityClass {
public NonActivityClass (Context context) {
Toast.makeText(context, "mymessage ", Toast.LENGTH_SHORT).show();
}
}
Hope this works for you...
I am trying to send the events from one Java class to Activity.
Scenario is, Will be having some data in the native, native will call the callback function which is in java code, This class processes data, after the processing i need to update the UI. I want to update the UI at one place in the Activity handler. (Dont want to use runOnUiThread() everywhere).
I was not able to send the events properly with the below approaches.
1st Approach:
1) Define functions for posting messages in to the queue and call these functions.
2) To call the above mentioned functions (point 1) we need context, if i maintain the static variable for maintaining the context and returning it, if the activity is created twice we wont able to get the write context for the first activity.
public class Activity1 {
protected static Context myContext = null;
protected Handler myHandler = null;
#override
public void onCreate() {
myContext = this;
myHandler = new Handler();
}
public static Context getMyContext() {
return myContext;
}
public void postEvent1() {
myHandler.sendMessage();
}
}
2nd Approach:
1) Making the handler as a static variable and returning this with the help of static function. - Not a good design to expose the internal variables.
2) Cons will be like above, when a second activity is created.
public class Activity1 {
protected static Handler myHandler = null;
#override
public void onCreate() {
myHandler = new Handler();
}
public static Context getMyHandler() {
return myHandler;
}
}
Is it possible to get the activity context without using the static variables and static functions?
Please share the knowledge if anyone knows. :)
Thanks & Regards,
SSuman185
I used a container class HashMap for storing the contexts with the key.
I used the name of the class as the key.
When the second activity is trying to register with class containing hashmap, it will reply with context of the already stored activity (null if not).
So like this I am able to store the contexts' of the classes and avoid loosing of the first activity context if I am creating the second one.
Please add if any one gets better solution.