I want create a own class with utility functions.
Therefore i want to use typical Activity-functions and build something around them.
I want use the setTitle function for example:
public void frameworkSetTitle() {
String testValue;
setTitle(testValue);
}
Is it possible to use this functions in own classes and pass the result back to the calling Activity?
You have to pass the Activity instance to the util method and call the desired methods there, like setTtitle.
This functionality is not recommended, as passing around context can lead to unintended memory leaks. Flow of information should be uni-directional, anyway.
Your util class should do something more like this:
public static String getGeneratedTitle() {
String titleValue;
// some work
return titleValue;
}
This way, you can just make a simple call in your activity:
myTextView.setText(myUtilClass.getGeneratedTitle());
Related
I'm in the process of completely redesigning my Android app. Before, EVERYTHING was in the same class.
So I tried to redraw everything so that the code is clearer apart Admob than the doc advice to put in the Main thread, I separate the different part of my code in class. So I used two technique: I created a songleton that contains variables that I want to have access to constantly,and I call my classes via weak reference.
Here is what it looks like:
For example, the UIManager class that needs to update the game's IU have a weak reference looks like this:
private static SoftReference<UIManager> ManageUI;
static{ManageUI= new SoftReference<>(null);}
static UIManager get()
{
if(ManageUI.get()==null)
{
ManageUI= new SoftReference<>(new UIManager());
}
return ManageUI.get();
}
GameManager Manager=GameManager.getInstance();
to be able to use the findviewbyid for example I place in method argument the main class that is the mainthread
the singleton that contains all my variables that I want to have permanent access to looks like this:
private GameManager()
{}
/** Holder */
private static class Manager
{
/** Instance unique non préinitialisée */
private final static GameManager instance = new GameManager();
}
/** Point d'accès pour l'instance unique du singleton */
public static GameManager getInstance()
{
return Manager.instance;
}
To separate all in different class, I pass argument to my method so I can call au stuff belong to Activity like that:
(My main class is called GamePlay)
void OpenGlobalScene(GamePlay activity)
{
Manager.OnTitle=false;
if (!checkLayout(activity,R.id.globalscene)) {
LayoutInflater(activity,9, true);
LinearLayout GamePlan = (LinearLayout) activity.findViewById(R.id.globalscene);
GamePlan.setAlpha(Manager.AlphaBord);
}
}
For now, I have not noticed any problems except a few slownesses on old android phone 4.4.2.
Also compared to my old code were EVERYTHING was in the same class, it's much easier to change pieces of code (going to the inapp billing V3 was simpler since everything was in one class that I call like the others with weak referencre)
My questions are:
-What are the problems that such a structure might pose?
I had also chosen that structure to not load or leave in memory things that are not useful
-How are chance that Android will erase from memory an action in progress called with weak reference?
-As you can see I pass the activity has argument to the method, sometimes I pass it from a method to another. Is that fact can cause some trouble?
Thank you for your help.
Check Dagger2 is better than the clasic singleton https://developer.android.com/training/dependency-injection/dagger-android?hl=es-419
thanks for your answer and your tips. I'am gonna check this out.
Anyone else know something about consequences on memory when using weak references ?
I developing an android application. I'm confused between two way to use static for customized UI component like dialog, progress bar or alert.
See below.
public class UiUtils {
public static void inputAlertDialogShow(Context context, final View view ,String message,DialogInterface.OnClickListener listener)
{
CustomDialog.Builder customBuilder = new
CustomDialog.Builder(context);
if(listener!=null) {
customBuilder.setMessage(message).setPositiveButton(context.getResources().getString(R.string.dialog_confirm), listener);
}else{
customBuilder.setMessage(message).setPositiveButton(context.getResources().getString(R.string.dialog_confirm),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
if (view != null) view.requestFocus();
}
});
}
customBuilder.create().show();
}
}
I made method showing dialog as static method. So I can call customized dialog to anywhere like
UiUtils.inputAlertDialogShow(context, view, message, listener).
But I can also use it like this
UiUtils ui = new UiUtils();
ui.inputAlertDialogShow(context, view, message, listener);
Can anyone explain me which one is better and why?
Utilities don't need to be instantiated. Utility class purpose is to provide the commonly used functions that's why all functions in Utility class are made static and they are called Utility.functionName so its better to call UiUtils.inputAlertDialogShow(context, view, message, listener).
Hope this helps.
UiUtils.inputAlertDialogShow(context, view, message, listener).
Call directly like above and one more thing and keep callback with you
when you call this function from any activity or fragment.
Hope it will help you !
you can't do it. when you define a variable as static, you can't make an instance to access it. static is the best way to access objects and method without make an instance. why you try to make an instance? do you know by making an instance, you reserve some memory?
There is just one thing you need to consider, are you writing testable code? If you want your code base to be testable then, static methods is not the way to go, because in order to test static methods of a class you need to use PowerMock, the basic Mockito library can't mock static methods. so in order to make the code base testable you need to not use static methods and use dependency injection to inject the UiUtils class to whichever class depends on the UiUtils
So if you want to know theoretically which one is better? Then not using static methods is better, because it makes for testable code.
you can use both method. because compiler will change it to static call like
Class.methodToCall();
refer this SO answer
and according to java practice, it recommend to call without object.
I need to pass objects to my fragments in order to initialize them.
Currently I am doing this with ((MyActivity)getActivity()).getX(). (direct access to the activity)
However, I would like to pass the required objects as parameter.
I definitely do not want to add parcelable objects to the bundle, since they require an excessive amount of useless boilerplate code. My goal is to reduce complexity, not increasing it.
And I do not want to add serializable objects to the bundle, since they are slow and cause an unnecessary overhead.
What is the best way to pass objects to fragments?
Any ideas to solve the problem in a more convenient way?
I definitely do not want to add parcelable objects to the bundle, since they require an excessive amount of useless boilerplate code. My goal is to reduce complexity, not increasing it.
You write this code in your model classes which is separated from your activities and fragments. There is no complexity in implementing Parcelable. And it is a common way to pass objects to a Fragment.
Any other solutions? Well, you still can do this ((MyActivity)getActivity()).getX() as long as your fragment is attached to your activity. In this case it is even faster than Parcelable because there is no serialization at all.
Other ways would be to write objects to database, pass their ids to a Fragment and then use a query to retrieve objects.
You can also use SharedPreferences, but that's rarely used. For this you will need to convert your object to String.
You can do the Android way: Parcelable.
You can serialize then.
You can do the poor way : static
You can do the retained way: Create a Fragment with setRetainInstance(true) and save your objects references.
I understand you don't want to use parcelable / serializable objects to a Bundle. I also agree with you since I got lazy, and my phone app is getting complicated.
Here's what you can do, and it works reliably.
Make a public method in your Fragment class, sample below.
Have the Activity, preferably no other place, call that public method. Remember Activity is always present, Fragments and Adapters may not due to its lifecycle.
The timing of the call is crucial if you're not using Bundles. I have used it without any problems.
The advantage of this technique is that it is fast, especially compared to Bundles. Many developers do not consider this however.
Note: If you are using simple fundamental Java types, do use Bundles! As suggested by Google.
Sample code:
public class MyFragment extends Fragment {
...
public void setList(final ArrayList<String> arrayList) {
...
}
In the Activity:
MyFragment fragment1 = MyFragment.newInstance(<parameters>);
fragment1.setList( arrayList );
Do you need to change the properties once they have been set on the fragment? If not, you can use setArguments(Bundle). If it is a fairly light object you can even skip implementing Parcelable and just set each property individually. The advantage is that the arguments are preserved upon orientation change. The disadvantage is that you need to call this method before attaching your fragment, hence it is not very useful once the fragment is in use.
It's way too late for my answer, but if someone else is wondering. The recommended way is to use Parcelable or Serializable, but you can always do something like this:
public class ObjectManager {
private static final String TAG = "ObjectManager";
private static ObjectManager instance;
private Object currentObject;
public static ObjectManager getInstance() {
if (instance == null)
instance = new ObjectManager();
return instance;
}
public Object getCurrentObject() {
return currentObject;
}
public void setCurrentObject(Object object) {
this.currentObject = object;
}
}
And then use it: where you needed as long as your app is running
//Use on the object you would like to save
ObjectManager.getInstance().setCurrentObject(object);
//Get the instance from pretty much everywhere
Object = ObjectManager.getInstance().getCurrentObject();
You can use it always, but it will be most likely to be useful, if you pass objects bigger than the Bundle max size.
I have more than 50+ activities in a single project so each and every time I need to write code to move a single activity from one to other.
What is in my mind, may I make a single function which can move more than one activity from a single static method of a class?
Like given in code below.
public static void moveActivity(Parameters)
{
//Code to move activity
}
Or may I follow any other idea for the same.
Any help would be really appreciated.
Thanks in advance.
What is in my mind, may I make a single function which can move more than one activity from a single static method of a class?
I believe not because startActivity needs a Context which can't be used in a static context, I believe.
Or may I follow any other idea for the same.
This depends on what you are doing but maybe ViewPager and/or Fragments could make your life easier. If you have that many Activities then most likely you won't want to try and manage them all from one function anyway because you have to consider extras, flags, etc... You will have two lines to start an Activity (sometimes more) just write the code. What you are trying to do will most likely result in more headaches, IMHO.
If there is a lot of the same data that you are passing around and that is your concern then you can use Bundles to pass them all around.
Try this:
public class Utils {
public static void launchActivity(
Class<? extends Activity> nextActivityClass,
Activity currentActivity, Map<String, Integer> extrasMap) {
Intent launchIntent = new Intent(currentActivity, nextActivityClass);
if (extrasMap != null && extrasMap.size() > 0) {
Set<String> keys = extrasMap.keySet();
for (String key : keys) {
launchIntent.putExtra(key, extrasMap.get(key));
}
}
launchIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
currentActivity.startActivity(launchIntent);
}
}
To use it:
From your activity class, make this call:
Utils.launchActivity(ActivityB.class, this, extrasMap);
When I'm writing a method or using a member variable, I often find I need to share them across an app. But where should they go?
I can subclass Activity, but that falls over as soon as I use a MapView and am forced to use MapActivity, so not all my activities inherit from my subclass. Is there I way around this?
Where inheritance isn't applicable, I am tending to put generic methods and member variables into a subclass of the Application object, but I'm finding it's creating a mess of code as every class needs to either grab access to the application object through via context, or I have to pass it down.
I suspect I would be better off creating MyApplication.getInstance() and keeping everything in a singleton, instead of passing the application object down through the app classes. but before I wanted to see what you guys had to say.
If you want to access the "Global Singleton" outside of an activity and you don't want to pass the Context through all the involved objects to obtain the singleton, you can just define, as you described, a static attribute in your application class, which holds the reference to itself. Just initialize the attribute in the onCreate() method.
For example:
public class ApplicationController extends Application {
private static ApplicationController _appCtrl;
public static ApplicationController getAppCtrl()
{
return _appCtrl;
}
}
One example with resources: Because subclasses of Application also can obtain the Resources, you could access them simply when you define a static method, which returns them, like:
public static Resources getAppResources()
{
return _appCtrl.getResources();
}
For global methods, use a static Util class with static methods. If you can't use static methods, then the methods shouldn't be global in the first place, and put them in the class that makes sense.
First read this:
How to declare global variables in Android?
Now why you shouldn't use a static singleton. Using a singleton is a the same thing as a global variable. Global variables reduce your maintainability because everywhere you use the global variable you break modularity or introduce global details and assumptions about your overall design. Your program can't have two of these variables because it only looks in one place for it. This means your program can't adapt easily when you have two instances instead of one.
For example, say I have a method called playTurn() and I implement it like so:
public void playTurn() {
globalPlayer.incrementClock();
globalPlayer.doSomething();
globalPlayer.doSomethingElse();
}
Now let's say I want to add a second player to the mix. Uh oh my playTurn() method assumes one player only when it used globalPlayer. If I want to add a second player to the program I have to change that method. Do this a lot and your program is very rigid and inflexible to change. Instead what if I did this:
public void playTurn(Player player) {
player.incrementClock();
player.doSomething();
player.doSomethingElse();
}
Now can do this:
playTurn( player1 );
playTurn( player2 );
I can reuse playTurn() for both player1 and player2 and I didn't have to change it. I just had to change the client of that method.
Most of the time you're being lazy and you want to get a reference to some object, and global variables are fast ways to get references to well known objects. Instead it's better to have one class that resolves the dependencies across your application at start up or the time when it makes sense. Then only that one place understands how your code is put together. For example,
public class Game {
Player player1;
Player player2;
Board board;
public void startGame() {
BlueTooth blueTooth = BlueTooth.getChannel();
player1 = new LocalPlayer();
player2 = new NetworkedPlayer( blueTooth );
board = new Board();
player1.setOpponent( player2 );
player1.setBoard( board );
player2.setOpponent( player1 );
player2.setBoard( board );
}
}
Now everyone has their dependencies, and they don't need to use static variables to find references to things. Also player1 doesn't have to know about details like that player2 is over the network, or that it's apart of a Game. What's important to note is that these objects we're connecting have a long life, possibly the entire program, but if they need to create other things at runtime that's ok for them to do.
Say for example, we need to create multiple players at runtime based on who joins the game. Well we might create a PlayerManager that we can instantiate at startup then create Player objects on the fly. PlayerManager is just a plain old object that we create in Game when we start a new game.
I hope you can start seeing this is a much better way to develop software. You might not understand it right off, but if you think about it will make more sense. It's very subtle change, but very powerful.