How to postpone nativeactivity call untill java objects are initialized? - android

I am attempting to initialize some variables in java and then send them to my native code. I need to delay the nativeactivity call so that the java variables get time to get initialized and then they can be passed to the native activity.
My main problem is that the native activity keeps being called as soon as my activity starts as i have extended my class from NativeActivity(which is compulsory). As soon as onCreate() is called after super my native activity automatically is started and my java variables are not initialized yet.

You can use handler into your class.
Below is my code which is working to perform delay operations:
private void cal(){
final Handler handler2 = new Handler();
Runnable runnable = new Runnable() {
int i=0;
public void run()
{
if(i==0)
{
// Enter your code here which you want run after some deley.
i++;
}
handler2.postDelayed(this, 2000);
}
};
handler2.postDelayed(runnable, 2000);
}
Call this function into your main class.
Hope it will work for you also.
Thanks

Related

Will handler inside a method leak memory?

I know handler declared in a class may leak memory since it holds a reference to its outer class. In this case, we should use static nested class with weak reference.
But What if a handler is declared inside a method. I faced below case and not sure is it a correct implementation. Could someone please explain or give me a hint? I even don't know what I should search for.
private void methodA(){
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
methodB();
}
}, 10*1000);
private void methodB(){
//textView holds a reference to a activity
textView.setText("hello");
}
It can under certain conditions. If the runnable passed is an anonymous or inner class, as in your example, it holds an implicit reference to 'this' and prevents 'this' from being garbage collected until the runnable is processed off the queue (so if your method never runs, like if your handler thread gets stopped without clearing the queue, it will leak).
In the case where you are worried about the conditions for a memory leak occurring or hanging onto objects too long, then you need to make your runnable a static class that has a weak reference initialized in the constructor, something like:
private static MyRunnable implements Runnable
{
private final WeakReference<MyClass> myClass_weakRef;
public MyRunnable(MyClass myClassInstance)
{
myClass_weakRef = new WeakReference(myClassInstance);
}
#Override
public void run()
{
MyClass myClass = myClass_weakRef.get();
if(myClass != null)
myClass.methodB();
}
}
private void MethodA()
{
Handler handler = new Handler();
handler.postDelayed(new MyRunnable(this), 10*1000);
}
Creating a Handler inside your method isn't a special case. It falls under the same circumstances, in that the Message you post will live in the message queue until it's processed.

Is it OK to use previous Handler in Activity created before onDestroy() onPause()?

Is it OK to reuse a Handler object in the next life of Activity which was previously created in its previous session (before onPause, onDestroy()) ?
Like I create a Handler in Activity propagate it to other objects elsewhere, the Activity dies or pauses, then comes to life again and use the old handler ?
// In the oncreate() method I have this code to recreate handler every time
// Then I set the handler to a static Global object
// Other Objects use the global object's static method to get
//fresh handler every timebefore calling sendMessage()
/**
* Set up handler
*/
Handler h = new Handler(new Callback()
{
public boolean handleMessage(Message msg)
{
handleServiceMessage(msg);
return true;
}
});
uiglobal = new UIGlobals(h);
UiGlobals is declared as
private static UIGlobals uiglobal = null;
Not sure if the above approach is correct ..
my GlobalUI class looks like this
public class UIGlobals
{
private static Handler handler = null;
public UIGlobals(Handler h)
{
handler = h;
}
public static Handler getHandler()
{
return handler;
}
}
If you have build your custom Handler class this should work but if you have defined your customized handler in your activity you have to unregister all handler messages in onPause. Otherwise you get a null pointer exception.
But i dont know in whick scenario you need this functionality... I normalley use Handler for UI access but for communication between activity and logic observer pattern.
If your handler is static and the Application (not the activity) hasn't been removed from memory, next time activity starts, static objects will be there.
If your handler is static and the Application has been removed from memory (i.e. service, threads, etc. are all stoped and you exit the only active activity) the next time you start activity, the Aplicationobject will be restarted and static objects will be recreated.
If your handler is not static, the you should be recreating it everytime you create activity, and of course, you will get a new one.
You need to post code or be more specific on your situation, if you want to have a more concrete answer.

Callback to activity from other class

I have Activity class, Controller class (normal java class use to control number of activity) and BusinessEngine class (normal java class use to process data).
When I need to do some calculation from activity, Activity will call Controller and Controller will call BusinessEngine to do the calculation. When BusinessEngine done with the calculation, it will pass the value back to Controller and finally let the activity know the calculation is complete.
The problem is how I callback Activity from Controller class? Or pass any data to Activity and notify it the data has been change?
Any "long" running tasks must be performed in a background thread. I'm not sure if your currently doing this for your task, so just in case your not, there are a couple of ways to do this. The first is to simply use a AsyncTask, the second is to create your own instance of AbstractExecutorService (AsyncTask uses ThreadPoolExecutor) and use that to post Runnable or Callables to. The later way may save you a lot of re factoring depending on your code base.
Assuming you're now running the task in a background thread, it's necessary to perform your UI updates on the UI thread. There are again a couple of ways to do this. One method is to post a runnable to the method Activity#runOnUiThread, the second is to use a Handler which has previously been created on the UI thread (which Activity#runOnUiThread does behind the scenes).
So, assume your Activity has a method #postResults(final Object o), and your controller has the method #doSomething(final Activity activity).
Your activity would look something like this.
public class MyActivity extends Activity {
Controller controller = ....
ExecutorService service = Executors.newFixedThreadPool(10);
private void startTask() {
Runnable r = new Runnable() {
public void run() {
c.doSomething(MyActivity.this);
}
}
service.submit(r);
}
public void postResults(final Object o) {
Runnable r = new Runnable() {
public void run() {
// Update your UI here
}
}
runOnUiThread(r)
}
}
and your controller
public class Controller {
public void doSomething(final Activity activity) {
// Perform some long running task here
activity.postResults(someObject);
}
}
Obviously this example could be tidied up (for example passing a interface to doSomething rather than the Activity), but hopefully it should be enough to understand what you need to do :)
Why are you looking for the controller to call you Activity? Normally, your Activity must call the controller via its methods and directly get results from them:
// Code in your Activity
result = controller.doSomething(args);
try using a android AsyncTask, if your method takes a long time to process. example
Add your classes to an Async task or if you're calling the classes and passing them from one class to the other.I would say to use static class. And provide some code so we can know how you are passing your data.
If not use general methods to call the superclass or the subclass.
My answer is a bit abstract as information is less.

Android's Activity.runOnUiThread is not static, so how can i use it?

For example, if I have a thread doing expensive stuff, and from that thread I want to fire runOnUiThread in the Main (activity) class. Obviously I shouldn't make an instance of my activity class (Main). So if I try
Main.runOnUiThread(mRunnable);
from my thread it gives me an error saying it's not a static method, and therefor it can't be accessed in my way. Now my understanding would be that the activity class is nearly almost accessed in a static way.
How would I do this?
(Btw: I'm doing this because I was getting CalledFromWrongThreadException, Only the original thread that created a view hierarchy can touch it's views)
Raunak has the right idea. I'll just add that you can also specify an integer in the method sendEmptyMessage as an identifier to the handler. This will allow you to create one handler that can handle all of your UI updates, e.g.
public static final int EXAMPLE = 0;
public static final int ANOTHER_EXAMPLE = 1;
private final Handler handler = new Handler(){
#Override
public void handleMessage(Message msg) {
switch( msg.what ){
case EXAMPLE:
//Perform action
break;
case ANOTHER_EXAMPLE;
//Perform action
break;
}
}
}
//Call to submit handler requesting the first action be called
handler.sendEmptyMessage(EXAMPLE);
Hope this helps!
You should use the Handler class. The handler class runs on the UI thread. When you finish work in your thread, call handler.sendEmptyMessage(), from where you can make the changes to your ui.
private final Handler handler = new Handler(){
#Override
public void handleMessage(Message msg) {
// make changes to ui
}
}
Your question doesn't really provide enough details, but from the sound of things, you're in a private inner class (Runnable?) in your activity (Main). If that is the case, you can either write:
Main.this.runOnUiThread(mRunnable);
or
runOnUiThread(mRunnable); //will see that there is no runOnUiThread in the current class and begin looking "upwards"
Also, you may want to look at AsyncTask, specifically at the onPostExecute, onPreExecute and onProgressUpdate callbacks, which run on the UI thread.
first create a runnable outside onCreate. Like this:
private Runnable myRunnable = new Runnable() {
#Override
public void run() {
//work to be done
}
};
and then call the runnable using:
runOnUiThread(myRunnable);
all of the above answers are not very correct.
1)if you want a piece of code to run on UI thread from any thread code base. you can do:
Looper.getMainLooper().post(new Runnable(...))
because Looper.getMainLooper() is a static variable and initialized in ActivityThread.
2) if your runnable code snippet is inside an activity
then you can use:
MainActivity.this.runOnUiThread(...)
For those who are looking for an easy instant solution follow the simple steps
Make a reference of your class before your onCreate() method
MyClass obj;
Initialize it in you onCreate() method
obj = MyClass.this;
Call runOnUiThread()
obj.runOnUiThread(new Runnable() {
public void run() {
//perform your UI tasks here
}
});
Hope it helps.

Unit testing Handler

I am ultimately trying to unit test a custom base adapter, but I am stuck at one point: I am unable to figure out how to get the UI thread to process the message I have just passed to it via sendEmptyMessage(...).
In my Activity I have a "addFoo(Foo foo)" method that updates an array and then calls "sendEmptyMessage(1)", and I have a handleMessage method that calls the ListView's adapter to tell it the data has changed.
I've boiled the unit test down to, roughly:
public void testAddFoo() {
Foo foo = new Foo();
assertTrue(mActivity.addFoo(foo));
assertTrue(mActivity.getHandler().hasMessages(1));
assertFalse(mActivity.getHandler().hasMessages(1));
assertTrue(mActivity.fooListNotEmpty());
}
Naturally it is failing on that assertFalse() (this is a contrived example, simplifying it as best as I can).
What call can I make in to mActivity or its handler or looper to get it to process all pending messages? I have tried some suggestions I've read about calling Looper.loop(), within the UI thread, but those are stabs in the dark and they failed.
FWIW, I'm pretty sure that the handleMessage code is correct because if I call it directly (inside #UiThreadTest) like so:
#UiThreadTest
public void testAddFoo() {
Foo foo = new Foo();
assertTrue(mActivity.addFoo(foo));
Message msg = Message.obtain();
msg.what = 1;
mActivity.handleMessage(msg);
assertTrue(mActivity.fooListNotEmpty());
}
the test ends up working as expected.
If your Activity implements Handler.Callback and you want messages to show up in your handleMessage method, then you need to pass in your Activity when you initialize the Handler in onCreate.
mHandler = new Handler(this);
I know you got the member Handler approach working, but I'm adding this for people like me who show up here trying to figure out how to get the Handler.Callback interface approach working.
If you are implementing Handler.Callback in your activity then you should just do
assertTrue(mActivity.hasMessages(1));
otherwise do not implement the callback and use
mHandler = new Handler() {
// override Handler methods as required
// ie handleMessage(Message msg)
};
and
assertTrue(mActivity.mHandler.hasMessages(1));

Categories

Resources