I have a inner static class which extends thread inside my main Activity. In this Thread, I need to call a non-static method from my main Activity.
As I see, I have 2 options:
Make my non-static method static: This option would not be feasible cause inside this method I call startActivityForResult and I can't call this in a static way.
Create an object of my main Activity inside the inner static class, and call the method via this object.
MainActivity mActivity = new MainActivity();
//...
mActivity.method();
The one I'm using now is the second, but I have a doubt about it. If I do this, I understand that I'm creating a new instance of MainActivity, and doing this, are all definitions in onCreate method called? Or I'm just calling the method and the variables I'm using inside will be null?
UPDATE --
This is the inner class where I need to call the method from main. I need this to be static because the base functionality of the app needs it to be this way. Now I'm introducing a new method in main activity that must be called when an action happens inside the thread:
private static final class DetectionThread extends Thread {
//...
public DetectionThread(byte[] data, int width, int height) {
}
#Override
public void run() {
//DO STUFF HERE
//Action happens and calls the method from main activity:
SpeechWhenMotion();
//...
}
}
}
And this is the header of the method which is defined in the main activity. Inside of it I'm calling to another method which starts activity for result, so this is the reason why I cannot set this method as static:
public void SpeechWhenMotion() {
//...
}
Assuming MainActivity is the outer class, I guess what you are looking for is
MainActivity.this.startActivityForResult()
Creating another object isn't the right solution.
And BTW, it's equally bad to create a class extending Thread. I don't see a reason you need to do so. For all you need to do unless sophisticated threading, all you need to do is to implement Runnable(). Doing so properly segregate your threading concern from your business logic.
Pass a MainActivity instance to your static method. Then call .method() from that instance.
static void doSomething(MainActivity ma) {
ma.method();
}
This, or the 2nd option that you posted.
Related
The first problem is i have java class with 500 lines. That will so bad, so i want to split them. I found solution in another stackoverflow thread that, we can pass main class context to another class.
//main class
Public class Main{
#Override
Public void onCreate(Bundle inst)
{
Super.onCreate(inst);
ClassB bclass = new ClassB(this);
bclass.setLayout();
}
}
//B class
Public class ClassB{
Activity act1;
Public ClassB(Activity act)
{
act1 = act;
}
Public void setLayout()
{
this.act1.setContentView(R.layout.lay);
}
}
Okay, thats work. But how to make act1 be our main context? so every time i want call setContentView from ClassB i don't need to use act1 again
Edit 1:
What i hope is, i want to make act1 as default context for ClassB. So when i call setContentView from ClassB, its directly called to Main.setContentView
Because if i just call setContentView from ClassB, i wi get NullPointerException. Its make a sense since ClassB have no context
Not sure why you are doing this. There are ways to reduce lines of a single java class instead of keeping UI references in other classes or rendering UI by other classes. You can encapsulate your business logic(Not UI) in other classes which can improve the readability of your code or in your case, if you have multiple Activities which have similar behavior, you can create a base abstract activity class and put all the base code to it.
What I want to do is like this. My question is how can I call tm.test in inner.
// TestMain is a class implemented handler
public void outer() {
inner(TestMain::test); // call inner
}
public void inner(handler h) {
TestMain tm = new TestMain();
//invoke tm.h(), i.e. invoke tm.test() in this example
}
public interface handler<M> {
void entitySelector();
}
I know how to call tm.test in inner if tm is declared in method outer, i.e. pass the function as tm::test
But I have to declare the instance every time I call inner.
Simply spoken: you can't. And even it would be possible, you shouldn't do something like that.
There is the "principle of least surprise": you don't that people reading your code tell you "wtf?!" because your code surprises them.
In other words: you should step back and see if your design really makes sense this way. Can't you use a fixed tm instance for example; one that sits as field on your class; instead of being a local variable in your method?
I have the following code:
public class Application extends ApplicationManager{
public static void main(String[] args) {
ProcessUtility.enableProcessUtility();
new Application().start();
}
}
and the class ApplicationManager code:
public class ApplicationManager {
public ApplicationManager() {
String configPath = "file:home" + File.separator + "log4j.xml";
System.setProperty("log4j.configuration", configPath);
logger = Logger.getLogger(ApplicationManager.class);
}
protected void start() {
logger.info("*** Starting ApplicationManager ***");
}
when I run the application class the start method of the parent will be called, can it be called without calling the parent default constructor?
my second question is the above code different from this code:
public class Application extends ApplicationManager{
public static void main(String[] args) {
new Application().start();
}
#Override
protected void start() {
ProcessUtility.enableProcessUtility();
super.start();
}
}
and the ApplicationManager class as above.
this is the code of the static method:
public static void enableProcessUtility() {
isCommon = false;
}
thanks in advance.
Calling a non static method (your start method) requires creating an instance of the class that contains the method (or a sub-class of that class). Creating an instance of a class requires invoking the constructors of the class and all its ancestor classes. Therefore you can't avoid executing the parent default constructor.
As for the second question, moving ProcessUtility.enableProcessUtility() to the sub-class's start method means that it will be executed each time you call the start method.
That said, in your example your main only creates one instance of Application and only calls start once for that instance. Therefore ProcessUtility.enableProcessUtility() will only be executed once in both snippets, and the behavior would be identical.
EDIT: Another difference between the two snippets is that the first snippet calls ProcessUtility.enableProcessUtility() before creating the Application instance, while the second snippet first creates the instance and then calls ProcessUtility.enableProcessUtility() from within start of the sub-class. If the behavior of the constructors (of either the sub class or the super class) is affected by the call to ProcessUtility.enableProcessUtility(), the two snippets may produce different outputs.
Your first question is answered here https://stackoverflow.com/a/10508202/2527075
As for your second question, the super constructor will be called before the ProcessUtility call in the second example, where in the first example the ProcessUtility call comes first.
I currently have a parent class which has two subclasses and what I essentially want to do is have them both inherit a shared variable (a float). I need to set the value of the float in subclass1 and then use the value of the float in subclass2. I should add that these are all android activities and that subclass1 is at the beginning of a chain of activities and subclass2 is at the end of this chain, all the activities in between are also children of the same parent class.
What I currently have is something similar to the following:
(I've left a lot of the other code out this is just the bare bones)
class activityParent extends Activity{
public static float value;
public void setValue(){
//grab the value from phone (ill leave this code out and will hardcode a value below as an example)
value = 0.6f;
}
public void useValue(){
//where i use the value in another function here
otherFuncion(value);
}
}
class subclass1 extends activityParent
{
#Override
public void onCreate(Bundle bundle){
setValue();//need this to be initialized first
super.onCreate(bundle);
}
}
class subclass2 extends activityParent{
//some previous code here
//i need to use the value just before the activity finishes
useValue();
finish();
}
That float value is never used anywhere else.
This approach just seems wrong and I know it but I'm not sure how to go about implementing this properly.
I was thinking about passing data with intents but as mentioned the two subclasses arent in direct contact with each other, theres a series of activities between them and I'd rather not have to string this data through them all just to reach the end.
There is FAQ discussed in below link.
How do I pass data between Activities/Services within a single application?
Ideally, since you want to share a primitive data type (a float), Intent is recommended. But since this does not fit well with your requirement, you may skip this.
Next, using "static" (which you are currently doing) is also fine. You can access these static fields from any other class in your application.
But, if you want to have an alternate, then "Singleton" class can be used. This is a class that is designed to have only one instance.
public class Singleton {
private static Singleton INSTANCE ;
private Singleton() {}
public static synchronized Singleton getInstance() {
if(INSTANCE == null){
INSTANCE = new Singleton();
}
return INSTANCE;
}
}
It has a static method with a name such as getInstance() that returns the instance; the first time this method is called, it creates the global instance.
For example activity subclass1 may retrieve the instance and call setValue(0.6); later activity subclass2 may retrieve the instance and call getValue() to retrieve the last set value.
Be very carefull with a cascade of classes. The onCreate() of a SubClass1 calls super.onCreate() which is the onCreate() of ActivityParent. This may trigger a chain reaction (the intent calling ActivityParent is still available to onCreate()).
I am trying to end an never ending circle. I need to call a void that is not static from another class. The reason that I do not make it static is that some things are very hard to make static. (Everything inside a static void needs to be static).
I am trapped in a circle where I need to call a non static void from another class. I can not make it static because it some code do not like to be passed.
Till now I solved it sort of by a handler:
public static void change(){
//This is called to change a boolean
start=true;}
private void startDone(){
int timeBetweenChecks = 50;
final Handler h = new Handler();
h.postDelayed(new Runnable(){
public void run(){
if (start==false){
startDone();
} else{
//Do something
}
}
}
}, timeBetweenChecks);
};
The problem with this is that I have to run a handler that is checking if something has changed pretty often(In my case).
Is there any way of calling the non static startDone() directly?
If you are asking if there is a way to call a non-static method of a class without instantiating an object of that class, then no.
If I don't own a dog, I cannot tell my dog to sit.
The answer to your question is: No, you cannot call a non-static method from a static method without an instance of the class containing the non-static method.
To solve your problem: maybe the best way would be to broadcast an intent from change().
Something like:
public static void change(Context c){
start=true;
c.sendBroadcast(new Intent("CHANGE_HAS_BEEN_CALLED"));
}
Then in the non-static code of your activity you can register a receiver like this:
IntentFilter filter = new IntentFilter();
filter.addAction("CHANGE_HAS_BEEN_CALLED");
registerReceiver(new BroadcastReceiver() {
#Override public void onReceive(Context context, Intent intent) {
if (start==false){
startDone();
} else{
//Do something
}
}
}, filter);
By definition, if startDone() is non-static, then it makes no sense to call it unless you've instantiated the class that contains it. A non-static method is an instance method, which means it can return a different result for every object of its enclosing type.
I think what you want is a class that only contains startDone(). You want to instantiate the class once for your entire application, and then be able to call startDone().
Suppose the class is called ItsDone. Instantiate it as a singleton, then return the singleton when you do a "new", and call startDone().
a handler that is checking
if something has changed pretty often (In my case).
Sounds like callback to me. You pass a piece of code to that "something", and this piece of code is executed by "something" whenever its state changes. If you have control over this "something", it's very easy to implement such behavior, if you don't (if "something" is a part of some library), it probably has this behavior implemented (of course, if it is well-designed).
Anyway, checking the state "something" by querying it every, say, 50 ms is not the way to go.
The accepted answear for this question is a better solution then the solutions that are already sugested. Hope this will help anybody googling.