Well, I'm at a dilemma here. I made my own class that uses the Bluetooth class from android but I'm not sure where to put it. Extending the android Bluetooth class seems like a good idea but I need to override the onActivityResult() which is only available to an activity class. So, where would I put my class so that I have access to onActivityResult() (keeping in mind the idea here is to use as few dependencies as possible)?
In other words, I want to move the Bluetooth code from the main activity to a separate class.
You should to use separate file for each class. You can create a folder "engine". For example: com.mycorp.myapp.engine. You can get access to onActivityResult() very simple. For example: MainActivity.onActivityResult(). Note: function should be public.
Or you can pass your activity to your CustomBluetooth's constructor.
public class CustomBluetooth {
private Activity mActivity;
/* Constructor */
public CustomBluetooth (Activity pActivity ) {
super();
this.mActivity = pActivity;
}
/* Your functions */
public int getResult() {
return this.mActivity.onActivityResult();
}
}
Alex. P.S. Sorry for my English:)
Add an interface to your Bluetooth class and implement the interface in your activity.
Related
This question already has answers here:
How do I share common functions and data across many activities in a single android application
(4 answers)
Closed 2 years ago.
I call a function in onCreate function of an Activity to refactor my code. I wonder where to declare this function that is potentially used in every Activity of my app.
What I have done (it works fine) is to create a function class with a companion object where all my global functions are declared. But my question is: Is it a good way to do like that?
I call a function in onCreate function of an activity to factor my
code. I wonder where to declare this function that is potentially used
in every activity of my app.
I would create a BaseActivity and let all your Activities inherit from it.
abstract class BaseActivity : AppCompatActivity() {
private fun init() {
// your code
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
init()
}
}
In case your init function does not depend on anything which comes from the subclass, you can just invoke it in onCreate each time (as shown above), otherwise make it protected and call it from the subclass (with parameters).
What I have done (it works fine) is to create a Function class with a
companion object where all my global functions are declared. But my
question is : is it a good way to do like that ?
It depends on if you need global shared state or not. In the first case using an object or a companion object would not be a bad idea.
If you don't need global state, or what to pass in whatever state to the utility function itself, a top level function would be sufficient.
Utils.kt
fun someUtilityFunction(foo: Int) {
// ...
}
You can create some BaseActivity or YourAppNameActivity and call your function inside its onCreate. Then, every activity that extends BaseActivity as usually will call super.onCreate() and therefore the code you need
As long you do not have shared (mutable) state (as it can lead to side effects, there is nothing wrong in placing common code into companion object.
You can have a BaseActivity you extend your Activities from, but I would try to avoid inheritance in favor of composition.
If your method is touching the activity's view then BaseActivity approach would be fine. But if it doesn't move it to some singleton ActivityHelper class.
Like said, BaseActivity approach (inheritance) comes with a cost. You should be able to make good design choices by not putting everything inside it which will eventually makes it more coupled.
Follow composition pattern only if you find your code is interfering with its lifecycle. There are a few registerLifecycle callbacks for activity or fragment that can help you.
It's a good practice to move all that common code to a parent class and make each activiy heredate that parent class, by the way creating a companion object its a good option only if you want to create a singleton, a singleton it's needed when you want to instance that object only once.
For example a function in baseActivity (parent class) to create an intent filter or add code to onCreate function
public class BaseActivity extends Activity {
public static final String FINISH_ALL_ACTIVITIES = "somecode";
public final IntentFilter INTENT_FILTER = createIntentFilter();
private boolean _started;
private IntentFilter createIntentFilter() {
IntentFilter filter = new IntentFilter();
filter.addAction(FINISH_ALL_ACTIVITIES_ACTIVITY);
return filter;
}
// region Blindaje de eventos ciclo de vida
#Override
protected void onCreate(Bundle savedInstanceState) {
// inside your activity (if you did not enable transitions in your theme)
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
super.onCreate(savedInstanceState);
try {
doOnPostCreate(savedInstanceState);
} catch (Throwable t) {
doOnErrorNoControlado(t);
}
}
Here is my scenario.
I have an android activity in which I want to abstract my I/O dependencies. The dependencies are represented by this interface (edited for brevity and simplicity):
public interface ITimeDataServer {
TimeRecord[] get(int userID);
void save(TimeRecord record);
}
What I want is for my activity to be able to call these interface methods, and leave the implementation to be supplied by the calling code. (Pretty standard, I think).
ITimeDataServer myServer;
int myUserID;
void loadRecords() {
TimeRecord[] records = myServer.get(myUserID);
// etc...
}
My difficulty is, how can I ensure that myServer gets set?
This seems like a common problem, but I can't find a clean solution.
My first thought would be that myServer would be passed in through the constructor, but Android activities aren't really instantiated with constructors.
I've come up with several solutions, but they're all icky in some way:
Icky Solution 1
Create a static method to launch the activity class which takes an ITimeDataServer parameter and stores it in a static variable from which the activity can access it:
private static ITimeDataSource theDataSource;
public static void launch(Activity currentActivity, ITimeDataSource dataSource) {
theDataSource = dataSource;
Intent intent = new Intent(currentActivity, MainActivity.class);
currentActivity.startActivity(intent);
}
This is icky because (a) the data source is static and not actually associated with the instance, and (b) a consumer could initiate the activity by the standard activity API rather than this static method, which will cause NullPointerException.
Icky Solution 2
I can create a Provider class which provides a singleton instance of ITimeDataSource, which needs to be initialized by the calling library before use:
public class TimeDataSourceProvider {
private static ITimeDataSource myDataSource = null;
public void initialize(ITimeDataSource dataSource) {
myDataSource = dataSource;
}
public ITimeDataSource get() {
if (myDataSource == null)
throw new NullPointerException("TimeDataSourceProvider.initialize() must be called before .get() can be used.");
else
return myDataSource;
}
}
This seems a little less icky, but it's still a little icky because the activity's dependency is not obvious, and since there may be many paths to launch it, it's highly possible that some of them would forget to call TimeDataSourceProvider.initialize().
Icky solution 3
As a variation on #2, create a static IODependencyProvider class which must be initialized with ALL dependencies on app startup.
public class IODependencyProvider {
static ITimeDataSource myTimeData;
static IScheduleDataSource myScheduleData; // etc
public static void initialize(ITimeDataSource timeData, IScheduleDataSource scheduleData /* etc */) {
myTimeData = timeData;
myScheduleData = scheduleData;
//etc
}
public static ITimeDataSource getTimeData() {
if (myTimeData == null)
throw new NullPointerException("IODependencyProvider.initialize() must be called before the getX() methods can be used.");
else
return myTimeData;
}
// getScheduleData(), etc
}
This seems superior to #1 and #2 since a failure to initialize would be much harder to sneak by, but it also creates interdependencies among the data types that otherwise need not exist.
...and other icky variations on that theme.
The common themes that make these solutions crappy:
the need to use static fields to pass non-serializable information to an activity
the lack of ability to enforce initialization of those static fields (and subsequent haphazardness)
inability to clearly identify an activity's dependencies (due to reliance on statics)
What's a nooby Android developer to do?
As long as these dependencies implement Parcelable correctly, you should be able to add them to your intent, then unparcel them as ITimeDataServer and get the correct class.
I found a nice solution here, in the least-loved answer.
I define the library activity as abstract and with no default constructor, but a constructor that takes an interface, like so:
public abstract class TimeActivity extends AppCompatActivity {
private ITimeDataSource myTimeDataSource;
public TimeActivity(#NonNull ITimeDataSource dataSource) {
myTimeDataSource = dataSource;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_time);
// do stuff with myTimeDataSource!
}
}
Then, the calling code can create a concrete subclass with its chosen implementation that does have a parameterless constructor. No static members, easy-peasy!
This allows you to abstract and inject all sorts of crazy behaviours! Woooo!
(Note that the concrete subclass activity needs to be manually added to AndroidManifest.xml, like all activities, or the app will crash when it tries to launch.)
I need a little help with my Interface. I think that i doesn't understand them at all.
So i created this interface to notify every classes that implements it when a certain event occurs.
public interface OnColorsChangeListener {
void onColorsChangeListener(ColorsProp colorsProp);
}
My class that hold the interface:
private OnColorsChangeListener mCallback;
... // other code
// the event occurs here so i call:
mCallback.onColorsChangeListener(mProps);
// but of course here i get an NPE becouse this is undefined in this class.. well, with some replies here i'll understand better how to use that for reach my point
The class that implements it:
public class ClassTest implements OnColorsChangeListener {
... // other code
#Override
public void onColorsChangeListener(ColorsProp colorsProp) {
Log.d(TAG, "Color changed! " + colorsProp.color);
}
i put this in 4/5 classes to be notified in the same time for the color change. I'm quite sure the reason is that I didn't understand very well how them works, so can anyone point me to the right direction? Thank you!
Explanation by example:
You have to instantiate your callback, & it has to be an instance of your class
private OnColorsChangeListener mCallback;
mCallback = new ClassTest();
mCallback.onColorsChangeListener(mProps);
However if you want multiple callbacks you will need to use the Observer pattern.
Simple example:
private List<OnColorsChangeListener> mCallbacks = new ArrayList<OnColorsChangeListener>();
mCallbacks.add(new ClassTest());
mCallbacks.add(new OtherClass());
for(OnColorsChangeListener listener : mCallbacks) {
listener.onColorsChangeListener(mProps);
}
Obviously if you have the class, somewhere else you would not new it up, you would use that reference:
mCallbacks.add(mClassTest);
Observer Pattern Wikipedia
An interface is just a way to group together a bunch of related methods. Implementing this interface then requires you to implement all the methods grouped together by the interface.
The Java Tutorials has a good read on the subject:
What is an interface?
Here's a Stackoverflow thread regarding listener interfaces in android:
How to create our own Listener interface in android?
In short, you don't use the interface directly since it only specifies which methods implementing classes are supposed to implement.
I have created a service for TweetCollectorService. I want to call a method of another class in my service.can I do this Plz Help me.
Thankyou
Yes you can.. Only difference here is the method execution also occurs in background process.. No other difference..
Its not best practice to have other utility functions/methods in Activity, which mainly is to handle user interaction. so Strictly follow java convention and create different class which has all these methods, so it achieves cohesion.
You can dosomething like below..
Class YourActivity extends Activity{
public void do(){
// do your task
}
and in service just say new YourActivity().do()
}
Yes you can able to call the other class method. If you using your custom class then create the method as static so no need to create object of that class
suppose your custom class which extend Activity or not then also you can do like this way.
class CustomClass extends Activity{
public static void mymethod(){
// call me
}
}
now you can call into the service like this way without creating any object as explicitly
class MyService extends Service{
onCreate(){
CustomClass.mymethod();
}
}
For every Activity I add to my app I'm noticing a lot of similar code being used in the initialization of the Activity. A helper class with a static method to wrap this similar code seems the way to go.
I first thought of a singleton class. I could add static methods/variables and use them across the application. I haven't really tried to see how would this work in an Android application. Searching a little bit more I saw something about creating a class extending Application. For this I did a simple test:
public class MyApp extends Application {
public static String DEMOTEXT = "WORKING!";
public static void ShowToast(Context context, String text) {
Toast.makeText(context, text, Toast.LENGTH_SHORT).show();
}
}
MyApp.ShowToast(this, MyApp.DEMOTEXT); // Placed on onCreate of some Activity
This works exactly as I expected. Is this the way to go on Android or is there a better convention? Anything else I should consider when doing this?
By the way, should I use the final keyword on the string? What about the method?
EDIT: I just read this:
There is normally no need to subclass Application. In most situation,
static singletons can provide the same functionality in a more modular
way. If your singleton needs a global context (for example to register
broadcast receivers), the function to retrieve it can be given a
Context which internally uses Context.getApplicationContext() when
first constructing the singleton.
http://developer.android.com/reference/android/app/Application.html
Should I use a singleton then?
Application is primarily used for a global application initialization. You would create your own class, override Application.onCreate() and initialize your static application data there.
Dont forget to declare it in the AndroidMainfest.xml:
<application
android:icon="#drawable/icon"
android:label="#string/app_name"
android:name="your.package.path.to.MyApp">
A static helper class is made the way you did.
The convention is to use lower case letter at first position, so MyApp.showToast(...).
You would use final for the String if you would want to avoid madifications on other places (since it should be a contant).
// this would allow ...
public static String DEMOTEXT = "WORKING!";
// ... to do this somewhere else
MyApp.DEMOTEXT = "NOT WORKING!"
I haven't tried this but I think you should be able to do something like this as well.
public class MyActivity extends Activity {
private static final String DEMOTEXT = "WORKING!";
#Override
public void onCreate(Bundle bundle)
{
super.onCreate(bundle);
Toast.makeText(this, DEMOTEXT, Toast.LENGTH_SHORT).show();
}
}
Now for all activities that need to use that initialization could just extend your base activity class.
public class SomeActivity extends MyActivity {
...
// Should display the toast on create
...
}
Yes just use a singleton. Well in this case if your methods are static, you don't even need a singleton. Just a class with static methods.