My instrumentation is launching an activity to instrument it, but I can't seem to find an elegant way to tell when it's safe to start sending it my MotionEvent's. At the moment, I'm continually sending it MotionEvent's, and catching the SecurityException's that get thrown when the wrong application receives them.
The problem with this approach is that when the first event gets through, the application responds to it, so this method is not without side effects...
I was thinking of trying to do something with UID's, but I don't know where to look for that.
You might be able to leverage the standard Android lifecycle methods that get called on your Activity. You could set an 'infront' flag in onResume(), and clear it in onPause(). Then your instrumentation test just checks that flag to know when it's safe to send MotionEvents.
If you don't want to pollute your app by putting in code specifically for test purposes, create a subclass, override onResume/onPause, set the flags, and call super.
Related
For the purpose of profiling, I instrumented my android application so that it collects some log at the beginnings and ends of all functions. I do so by calling a public static method called keepLog(String log) at method boundaries. I also wrote another public static method called writeCollectedLogs() which is supposed to write all collected logs into disk. It is important that all logs are written at once because I do not want to use write system-call every time (instead I prefer to keep logs in memory and write everything on disk only once at the end)
My problem is I do not know where to call writeCollectedLogs(). I am looking for some onTerminate() method for the whole android app. However, non of android default onDestroy and onTerminate() seems to work in my case. It is important to note that I have 2 methods of running my application. Sometimes I run my app using android instrumentation test runner and sometimes I use adb to start activities and send touch events manually.
Instrumentation test runner opens my app, runs the tests and then closes the app. In the second scenario however, I have control over my app life cycle. I am looking for a universal way of calling for writeCollectedLogs just before the app closes.
Any suggestions?
This is a bit complicated because there is no universal answer for this problem. If you are using only Activities, onPause() is the only method that is always called (except application crash). Unfortunately, onStop() and onDestroy() are not called with 100% probability. However the android documentation advises to avoid CPU-intensive work in onPause().
I try to get the foreground activity for a long time, and i didn't managed to get it until now.
I don't know if it even possible, but i am dont intersted in my app activity only.
There is no data transfer between my service and the activity which i want to get.
I saw lot of questions of this kind but i got nothing suitable for my needs.
I just need to get an instance, not a ComponentName, not decription of the current foreground activity.
I've tried through ActivityThread, ActivityManager, ActivityManagerService (even though i couldnt get his instance too), and so on.
Field activitiesField = activityThreadClass.getDeclaredField("mActivities");// won't help
activityManager.getRunningTasks(rnd);// won't help either
If there is any refelection way, listener or something like that, but not a static field.
Without knowing why you want an instance of the Activity, or other background info. I'd suggest the following.
If you're inside a Fragment, then you can do getActivity() - which will give a reference to the Activity, and you can then cast this as your own Activity.
Otherwise, you might want to consider having a BroadcastReceiver, which can start an Activity for you.
You shouldn't be accessing an Activity directly. If you have methods/logic you need to access, you might consider refactoring them into a helper class.
Edit:
"Your application runs in a secure sandbox environment, so other processes on the system cannot access your code or private data." Take from the official Android docs
Im trying to use the pattern of Activity-Service-Messenger to comunicate my Activity and Service. (like explained here http://viktorbresan.blogspot.mx/2012/09/intentservice-and-inter-process.html) Basically it says that i should create a Handler inside my Activity, and then create a Messenger and send that via putExtra() to my Service. The Service would then post messages to the activity ussing the Messenger.
My problem is that if i rotate the emulator, the Handler associated with the Messenger holds a reference to a destroyed activity. This causes not to refresh the interface of the new activity. I tried to put Messenger in onSaveInstanceState(). Eventought i can save the Messenger, the Handler is still referencing my past activity and i cant find a way to retrieve my Handler from the Messenger to set the new activity.
Edit:
Im avoiding to using:
android:configChanges="orientation|keyboardHidden"
onRetainNonConfigurationInstance()
Edit:
I used HalR idea of using a singleton and keep the handler there. It works really good, althought i can see that this pattern implies a careful cleaning of the references on the singleton.
Finally im also testing on the idea of using Activity-Service that was commented by Hoan Nguyen
I'm not sure that its appropriate for this case, but there are many people who have been frustrated by losing their activity when it rotates, or having to set complex stuff up every time they get a new activity.
Some people will create singletons that they use for referencing, then keep the Handler in there.
Others will extend the application class and put stuff in there. If you have a lot of complex things you are wanting to set up once, those are techniques you can use.
Keeping your app fluid and your making your activities independent of one another is a better overall philosophy, so its best to avoid anything global, but sometimes you gotta do what you gotta do.
Rotating the device at least pauses and resumes your activity according to the lifecycle. I think you are aware of the consequences.
Maybe stopping and starting a new service is the only right solution here. i worked as well with global states, but it will just always be easier when, you make every activity independent like a "single application".
edit: ok it's a messenger service... so stopping and starting is not a solution. so maybe you can register and unregister your messengers.
Hiii i am testing a test method in which i want after a pressing a button my activity should alive so that i can see next test cases in that activity,but unfortunately my activity get killed after running the test case .is there any way to keep the activity alive.if there code line please let me inform.
I cannot be sure without seeing your code, but i am guessing either in the testcase, or the setup() and tearDown() methods you are going to have to been calling a method such as finishOpenedActivities() which closes all the activities you have open. removing this line will keep the activity open.
Having said that it is typically best practice to have your test cases start from a clean state because having test cases that rely on ordering means that if one fails all the others fail even if that functionality does work plus you have to do slightly hacky things in order to get them to all run in the order you want.
I dug into the source code a bit and found that the tearDown() method, as implemented in ActivityInstrumentationTestCase2, will make a call to finish() on your current activity. So even if you don't explicitly finish() you Activity in your implementation of this method, it will be done when calling super. However, per the source code documentation: removing the call to super in tearDown() can cause a memory leak if you have a non-static inner class, and, perhaps more importantly for your case, the running Activity seems to still be killed once the test is completed. Even if you have an empty implementation of tearDown(), it seems as though the Activity Under Test gets finished at the end of the run. As of right now, I don't know of a way to avoid this.
As an alternative based on your comment for #Paul Harris's answer, Robotium has many methods that allow you to wait for something to happen. You may want to look into waitForText() or waitForView(), which can take a timeout as a argument, to have Robotium pause while your button click is performing some action. Hope this helps!
Is there a way I can be notified of an application launch and termination in Android? I mean, more like subscribing to the Activity Manager and then determining which applications have been started and stopped...
My first instinct is to point you towards the BroadcastReceiver class, but checking the list of Intent flags available to listen for, I'm not seeing anything dealing with application startup/shutdown. I guess the best thing to do is start with this and see if there's some sort of acrobatics you can do that I'm missing in my quick glance.