How to Use sugar orm and google analytics at one project - android

Sugar ORM requires me to set my android:name as com.orm.SugarApp to function.
How can I use other libraries that also require my android:name to be changed?
I try :
public class Manage extends SugarApp {
#Override
public void onCreate() {
super.onCreate();
// do any thing
}
}
<application
android:name=".Manage"
...
>
t doesn't save any thing!
and after i remove app and test with
<application
android:name="com.orm.SugarApp"
...
>
it works but my stuf doesn't

In Pre-Versions It shows Force Close but in current version 1.4 ican solve it easy
I made Class Extends SugarApp but Sugar Context Didn't Initialized
public class Manage extends SugarApp {
// Here This Method Overrideed
#Override
public void onCreate() {
super.onCreate();
SugarContext.init(this); // Here This Method Called
LTH.dLog("Manage_TAG", "On Create Manage Class");
}
// Here This Method Overrideed
#Override
public void onTerminate() {
super.onTerminate();
SugarContext.terminate(); // Here This Method Called
LTH.dLog("Manage_TAG", "On Terminate Manage Class");
}
}

Related

Android: Gradle build task adds a final keyword to a method

I'm experiencing something strange, that never happened to me before.
This is simple class that extends an Application class:
public class MyApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
}
}
It is a library module, than I try to extend it from an application module:
public class MyApp extends MyApplication {
#Override
public void onCreate() {
super.onCreate();
Log.i("MyApp", "Application created");
}
}
Now when compiling with minifyEnabled=true I'm getting strange result:
In library module class get changed to (note the final keyword):
public class MyApplication extends Application {
MyApplication() {
}
public final void onCreate() {
super.onCreate();
}
}
And this causes compilation error, since MyApp cannot override a final method.
Did someone faced this issue?
Thanks in advance.
Happens only with minify enabled. Class MyApplication is added to proguard-rules as exception.
Happens only on Gradle > 7.1.3. Reverting to 7.1.3 fixes the cause.

Can I put Firebase ValueEvent listener in Application class

I want to use Firebase Value event listener in 5 activities. And all listeners are going to do same work, so can I put listener in Application class and remove listener when application is terminated?
public class MyApplication extends Application {
private RefWatcher refWatcher;
private ValueEventListener value_event_listener;
public static RefWatcher getRefWatcher(Context context) {
MyApplication application = (MyApplication) context.getApplicationContext();
return application.refWatcher;
}
#Override
public void onCreate() {
super.onCreate();
MultiDex.install(this);
EmojiManager.install(new IosEmojiProvider());
if (LeakCanary.isInAnalyzerProcess(this)) {
// This process is dedicated to LeakCanary for heap analysis.
// You should not init your app in this process.
return;
}
refWatcher = LeakCanary.install(this);
value_event_listener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
//TODO
}
#Override
public void onCancelled(DatabaseError databaseError) {
//TODO
}
};
FirebaseDatabase.getInstance().getReference().child(C.DELIVERY).addValueEventListener(value_event_listener);
}
#Override
public void onTerminate() {
super.onTerminate();
FirebaseDatabase.getInstance().getReference().child(C.DELIVERY).removeEventListener(value_event_listener);
}
}
Short answer, yes but there is a cleaner way to approach it.
A more SOLID approach would be to create a utility class that is called from each place you want to listen for this event. In this way you can extend the utility class should your requirements change in the future. The change can then be applied without potentially affecting all locations where this is used.
It also makes this more testable since you can mock out the utility class to verify different scenarios.

Is extending Application how you run code before the launching Activity?

If I do something like this:
public class MyApp extends Application {
#Override
public void onCreate() {
super.onCreate();
//init something else here if you want
}
#Override
public void onTerminate() {
super.onTerminate();
//terminate something else here if you want
}
}
And include the name of this class in the Manifest file like this:
<application
android:name="com.packagename.MyApp"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
Is this effectively giving us a way to run whatever code we want before and after the app runs?
Edit: If I step into the onCreate() statement I see this in the code:
/**
* Called when the application is starting, before any activity, service,
* or receiver objects (excluding content providers) have been created.
* Implementations should be as quick as possible (for example using
* lazy initialization of state) since the time spent in this function
* directly impacts the performance of starting the first activity,
* service, or receiver in a process.
* If you override this method, be sure to call super.onCreate().
*/
#CallSuper
public void onCreate() {
}
/**
* This method is for use in emulated process environments. It will
* never be called on a production Android device, where processes are
* removed by simply killing them; no user code (including this callback)
* is executed when doing so.
*/
#CallSuper
public void onTerminate() {
}
Edit 2: I could also save the application context as a global static variable:
public class MyApp extends Application {
private static Context context;
#Override
public void onCreate() {
super.onCreate();
MyApp.context = getApplicationContext();
}
public static Context getAppContext() {
return MyApp.context;
}
#Override
public void onTerminate() {
super.onTerminate();
}
}
Not before and after but in whole Application lifecycle, e.g. all running Activitys, Services and other contextual creatures... if none of them is currently visible/running Android system may always remove your Application from memory (user also).
If you are looking for a way to run some code outside screen/without any UI, check out Service class or other delayed alarm-basing method.
You can't depend on subclassing Application class because you don't even know when it is killed by OS "automatically".
Yes.
The main reason of having it extend Application class
Is to have all initialization that you want to be singletons
throughout the app and used in components.
Have some static variables
to be used across components
Ref: Logic why we should use

Android EventBus and base class

I am trying to implement some common logic and reaction to some events in base class of all my dialogues.
And registering and unregistering in EventBus, and catching some events in base class.
So when I tried to instantiate an instance of derived class - EventBus throws an exception that DerivedClass has no methods like onEvent(*).
I don't want to add some stub onEvent methods in every derived class, it is not the way software development should be.
It is so sad, if there is no way to use such approach about inheritance.
Did someone faced that?
You could make a protected method(or abstract class with abstract method) in the base class that you could override in child class(if needed), before registering EvenBus.
public class Test extends Fragment{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(doIneedEventBus()){
EventBus.getDefault().register(this);
}
}
#Override
public void onDestroy() {
super.onDestroy();
if(doIneedEventBus()){
EventBus.getDefault().unregister(this);
}
}
protected boolean doIneedEventBus() {
return true;
}
}
Child class:
public class TestChild extends Test {
#Override
protected boolean doIneedEventBus() {
return false;
}
}
Second option:
try {
EventBus.getDefault().register(this);
} catch (Throwable t){
t.printStackTrace();
}
Or you could wait until this issue is fixed in the library -
https://github.com/greenrobot/EventBus/issues/58
Use the rxbus2 library, which is compatible with base classes.
https://github.com/warrenth/RxBus2

Android - OnClick Listener in a separate class

Is it possible to make a secondary class to hold the OnClick Listener? Meaning not being created in the Activity class?
I just find that putting OnClick listeners in the main activity class is just messy and I would rather have them in separate classes. Thanks
Sure, that's possible. Just create a class that implements View.OnClickListener and set that as listener to the View. For example:
public class ExternalOnClickListener implements View.OnClickListener {
public ExternalOnClickListener(...) {
// keep references for your onClick logic
}
#Override public void onClick(View v) {
// TODO: add code here
}
}
And then set an instance of above class as listener:
view.setOnClickListener(new ExternalOnClickListener(...));
The parameterized constructor is optional, but it's very likely you'll need to pass something through to actually make your onClick(...) logic work on.
Implementing a class anonymously is generally easier to work with though. Just a thought.
Instead of putting the onCLicklistener in a separate class, why dont you try to define onClickListener outside onCreate()??
For e.g: like this
onCreate()
yourViewName.setOnClicklistener(listener):
Outside onCreate()
private OnClickListener listener = new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
};
Yes you can. However, making the listener an inner class has one advantage - it can access the fields and variables of your activity class directly. If you make it a separate class, and your listener actually need to access 5 views, your listener constructor might look like this:
MyListener listener = new MyListener(context, button, textView1, textView2, ratingBar, imageView);
Which is kinda bulky too. If your listener is simple, go ahead and make it a separate class. Otherwise, its up to you for readability.
Let me share how I code it using MVP. It's the best way to make clean code. Remember each class must have an interface to control it. I will show you the simplest one.
Suppose you want to Toast a text onClick and control it from another class. Here's how it works. Creating interfaces is for nothing but to connect with each other and you can review the code easily.
Create an interface for that MainActivity class.
public interface MainActivityView {
void showToast();
}
Create another interface for the Presenter class.
public interface IMainPresenter<V extends MainActivityView> {
/*Generic Type is to make sure it comes from MainActivity class only and to avoid other class to access it.*/
void onAttach(V mainView);
void onButtonClick();
}
Remember interfaces are nothing but to override method for each class.
Create a Presenter class
public class MainPresenter<V extends MainActivityView> implements IMainPresenter<V> {
private V mainActivityView;
#Override
public void onAttach(V mainActivityView) {
this.mainActivityView=mainActivityView;
}
public V getView() {
return mainActivityView;
}
#Override
public void onButtonClick() {
getView().showToast(); //This is the method from MainActivity controlling with this class
}
}
I'll skip, activity_main.xml layout because there's just a button with id="#+id/buttonId." In MainActivityClass,
public class MainActivity extends AppCompactActivity implements MainActivityView {
Button btn;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MainPresenter mainPresenter = new MainPresenter();
mainPresenter.onAttach(this);
btn = findViewById(R.id.buttonId);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mainPresenter.onButtonClick(); //Here, check No.3 again!
}
});
}
#Override
public void showToast() {
Toast.makeText(this, "Hello", Toast.LENGTH_SHORT).show();
}
}
All I want to tell you is that. If you create objects in a class, it cannot make unit testing. That's why you're not seeing any new objects calling in android. So, you can use a singleton pattern (Here is Lazy Type) in Presenter class. I'll remove its interface and Generic to see it clearly.
public class MainPresenter {
private static final MainPresenter mainPresenter = new MainPresenter();
MainPresenter() {}
public static MainPresenter getInstance() {
return mainPresenter;
}
//Some methods here can be get it once you create an object with getInstance();
}
And so you can get its methods from MainActivity like this.
Instead of creating objects like this...
MainPresenter mainPresenter = new MainPresenter();
You can get it like this...
MainPresenter mainPresenter = mainPresenter.getInstance();
More example for singleton pattern can be found here,
https://www.journaldev.com/1377/java-singleton-design-pattern-best-practices-examples
Finally, using static is not a very good choice because it uses memory space whether you use it or not. And so, you can create objects within Application Layer get it with a Typecasting. I'm sure you don't need to unit test that Application layer.
public class AppLayer extends Application {
private MainPresenter mainPresenter;
#Override
public void onCreate() {
super.onCreate();
mainPresenter = new MainPresenter();
}
public MainPresenter getMainPresenter() {
return mainPresenter;
}
And you need to give a class name within Application in manifest.xml
<application
android:name=".AppLayer"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
</application>
And you can get it with a Typecast in MainActivity like this!
MainPresenter mainPresenter = ((AppLayer)getApplication()).getMainPresenter();
For further studies, I suggest you learn ButterKnife, Dagger 2 and SOLID Principles. It will help you to create clean coding. Have fun!
You can do it. But just think that you will not have a reference to the activity, neither to it's attributes, including all the views. (unless you make them public or accessible with getters methods).
Also, be extra carefull with storing references to the activity or any members on the listener, since they might avoid the garbage collector from getting the listener memory back.
public class CommonClick {
public static void commonClick(final AppCompatActivity context){
context.findViewById(R.id.appbar).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
}
}

Categories

Resources