I'd like to use traceview to measure performance for several asynchronous events. The asynchronous events are passed to me in a callback that looks similar to the below code.
interface EventCallback {
void onStartEvent(String name);
void onStopEvent(String name);
}
where every asynchronous event will start with a "onStartEvent" call and end with an "onStopEvent" call.
I'd like to create trace files for every event. From my reading here (http://developer.android.com/tools/debugging/debugging-tracing.html#creatingtracefiles), it's not possible to trace asynchronous events since the ordering of the calls must be "structured" in a "stack" like ordering. So, the call to "Debug.stopMethodTracing()" always applies to the most recent call to "Debug.startMethodTracing("calc");"
So, if I receive callbacks in the following order.
onStartEvent(A)
onStartEvent(B)
onStopEvent(A)
onStopEvent(B)
which will get interpreted to
Debug.startMethodTracing("A");
Debug.startMethodTracing("B");
Debug.stopMethodTracing(); // will apply to "B" instead of "A"
Debug.stopMethodTracing(); // will apply to "A" instead of "B"
Using traceview, is there anyway to do what I want? i.e. trace "non-structured" asynchronous events?
traceview might be the wrong tool. If you really want to go this route you can keep an "active event count", and keep the tracefile open so long as there is an event being handled. This can result in multiple events being present in the same trace file, but you're tracing method calls in the VM, so there's no simple way around that.
If your events happen on different threads, you could separate them out with a post-processing step. This would require some effort to parse the data and strip out the undesirable records. (See e.g. this or this.)
You don't really say what you're trying to measure. For example, if you just want start/end times, you could just write those to a log file of your own and skip all the traceview fun.
Depending on what you're after, systrace may be easier to work with. Unfortunately the custom event class (Trace) only makes the synchronous event APIs public -- if you don't mind using reflection to access non-public interfaces you can also generate async events.
Related
We are building an Android application where we use Timber for Log-output. We have defined our own .e, .d, .v etc functions and use if (BuildConfig.DEBUG) to see if we should output the log. This takes care of the issue that we don't want to output Debug-logs in our releases but all the string literals used in our functions calls are still present in the compiled source code. We furthermore use ProGuard for obfuscation. To exemplify, in a class we can have:
somObj.normalFunction(variable)
Log.d("This secret class achieved its secret mission!");
In our release, this will not be seen in the app logs but if you reverse-engineer the APK you will see something like:
q.b(m)
z.a("This secret class achieved its secret mission!");
which can give a hint to the hackers about what class they are looking at.
So what we're looking for is to either be able to completely REMOVE all the Log function calls at compile time (using some pre-processing, annotation or something, but hopefully without having to add something before EVERY function call) OR to obfuscate all the String literal parameters to those function calls. So, two ideal solutions would be if the source, just before compilation, instead looks like:
q.b(m);
or
q.b(m);
z.a("jgasoisamgp23mmwaföfm,ak,ä")
Just by thinking I can see two bad ways to achieve this. Either we surround ALL calls to Log.d with if(BuildConfig.DEBUG) which will make the compiler remove them before compilation. But this is very tideous. OR, we make sure that every time you want to add a log-printout you need to do
Log.d(LogClass.getLog(1234))
and you then define ALL those logs inside LogClass and then remove them with if(BuildConfig.DEBUG) and return null in getLog if that's the case. But that makes it more tideous every time you want to add a log.
So finally, is there any GOOD solution to this?
DISCLAIMER: I work for PreEmptive, the company that makes PreEmptive Protection - DashO.
DashO is capable of removing calls to specific methods (e.g., Log methods). While this doesn't remove the instructions to load the string literal, just the call itself, DashO also offers String Encryption, which would offer some protection to those string literals.
As an example, I ran this class through DashO:
public class App {
public static void main(String[] args) {
Log.d("Secret message here");
}
}
After removing calls to Log.d with String Encryption on, the decompiled output looks like this:
public class App
{
public static void main(String[] paramArrayOfString)
{
a.replace("Bwpfpb7u|ih}z{?($0&", -12 - -61);
}
}
DashO offers other protections (e.g., Control Flow Obfuscation) that tend to break decompilers; I've turned those off for this demonstration.
What I would do is one or some of the following:
Use Timber (so you don't need to bother removing things or adding if statements). You simply do this once in your Application#onCreate(); if you are in DEBUG, then you plant a DebugTree that prints to the console. Else, you plant an "empty tree" that does nothing.
Simulate Timber but create your own "YourLogger" class and do the same (if you don't want to include a "third-party" library even though it's just one class). So you'd have YourLogger.v("tag", "string") and inside you'd do: if (debug) { Log.v(tag, string); } and so on and so forth for all other log types.
Use Proguard to strip the logging, and what not.
1 and 2 imply you go through your app and replace all Log. lines with either Timber. or YourLogger.
Option 3 wouldn't need that, since the code would be removed during obfuscation and the calls would do nothing, but this is mode complicated (and I haven't done it in years, don't even remember how it's done, probably easy to look it up).
I'd go for 1.
Update
Since apparently I don't know how to read, I think that in order to achieve this, your only bet is to have some sort of lookup mechanism for the actual text you want to emit/hide.
Strings.xml is the easiest, since it's included with Android and you can even localize the error messages (if that were needed, of course). Yes, there's a lookup time penalty, but I'd say unless you're iterating over thousands of items and logging different strings every time or something, the penalty wont' be noticeable (I don't have data for this, you'd have to benchmark).
Alternatively, instead of relying on resources, you could just use a file, read it, and load the strings in memory... a trade off; do you use more memory at the cost of simplicity and time to code the solution, or do you use the built-in mechanism and pay the CPU time?
The way I understand the HERE Android SDK is that there's a MapView that has a backing Map object. Adding objects, setting the center, zooming etc should be performed on the Map object and this eventually reflects on the MapView.
Question:
Are there any restrictions on what thread the operations on the Map object must be performed? For example, must they all be called on the UI thread? Also, should multiple subsequent calls be synchronized?
I ask this because I want to make multiple changes in a Map (resize the map view, change some visible layers, change the scheme, add a MapRoute and zoom out to the bounding box of the route). When I try this, it sometimes works but sometimes doesn't. Sometimes, only some of the operations are applied. For example, everything works except the zoom is not applied.
I know there are some listeners that can help me:
Map.OnTransformListener - this I can use to let me know when a zooming operation has ended
Map.OnSchemeChangedListener - this I can use to know when a scheme change event has ended
What is not clear to me from the documentation is what other operations constitute a "transform"? Which of these operations must be performed in a synchronized fashion?
For example, is the following code expected to behave correctly?
map.setCenter(coordinate, Animation.BOW, 18, 0f, 60f);
map.addMapObject(routeObject);
map.setVisibleLayers(layersToShow, true);
map.setScheme(Map.Scheme.NORMAL_DAY)
Note that in the above example, I'm proceeding to make changes immediately after setCenter even before the animation is complete. Is this the expected way to use the API?
There is no restriction on what thread you call the API from. Internally, all calls are synchronized and thread safe.
What you are looking for is the MapView#executeSynchronized API. [link] This will batch up a few operations into one screen redraw. [At least when I wrote that API a few years ago]
What you are experiencing happens because the underlying rendering thread started drawing some of the commands from the calling thread. This caused subsequent calls to lose effect.
In instrumentation tests, should I use com.robotium.solo.Solo#clickOnView or android.view.View#performClick?
Both of those functions require View object.
Checking javadoc and source code, functionality is similar.
But implementation is quite diffrent
android.view.View#performClick calls sendAccessibilityEvent then registered event listener.
com.robotium.solo.Solo#clickOnView(android.view.View) simulates actual finger click, on given screen coordinates (sends MotionEvent).
Are there any circumstances when should I use robotium function? It looks like it is just a lot of slower and more fragile way of having exactly same end result like android.view.View#performClick.
I will start this by saying that on iOS this algorithm takes, on average, <2 seconds to complete and given a simpler, more specific input that is the same between how I test it on iOS vs. Android it takes 0.09 seconds and 2.5 seconds respectively, and the Android version simply quits on me, no idea if that would be significantly longer. (The test data gives the sorting algorithm a relatively simple task)
More specifically, I have a HashMap (Using an NSMutableDictionary on iOS) that maps a unique key(Its a string of only integers called its course. For example: "12345") used to get specific sections under a course title. The hash map knows what course a specific section falls under because each section has a value "Course". Once they are retrieved these section objects are compared, to see if they can fit into a schedule together based on user input and their "timeBegin", "timeEnd", and "days" values.
For Example: If I asked for schedules with only the Course ABC1234(There are 50 different time slots or "sections" under that course title) and DEF5678(50 sections) it will iterate through the Hashmap to find every section that falls under those two courses. Then it will sort them into schedules of two classes each(one ABC1234 and one DEF5678) If no two courses have a conflict then a total of 2500(50*50) schedules are possible.
These "schedules" (Stored in ArrayLists since the number of user inputs varies from 1-8 and possible number of results varies from 1-100,000. The group of all schedules is a double ArrayList that looks like this ArrayList>. On iOS I use NSMutableArray) are then fed into the intent that is the next Activity. This Activity (Fragment techincally?) will be a pager that allows the user to scroll through the different combinations.
I copied the method of search and sort exactly as it is in iOS(This may not be the right thing to do since the languages and data structures may be fundamentally different) and it works correctly with small output but when it gets too large it can't handle it.
So is multithreading the answer? Should I use something other than a HashMap? Something other than ArrayLists? I only assume multithreading because the errors indicate that too much is being done on the main thread. I've also read that there is a limit to the size of data passed using Intents but I have no idea.
If I was unclear on anything feel free to ask for clarification. Also, I've been doing Android for ~2 weeks so I may completely off track but hopefully not, this is a fully functional and complete app in the iTunes Store already so I don't think I'm that far off. Thanks!
1) I think you should go with AsynTask of Android .The way it handle the View into `UI
threadandBackground threadfor operations (Like Sorting` ) is sufficient enough to help
you to get the Data Processed into Background thread And on Processing you can get the
Content on UI Thread.
Follow This ShorHand Example for This:
Example to Use Asyntask
2) Example(How to Proceed):
a) define your view into onPreExecute()
b) Do your Background Operation into doInBackground()
c) Get the Result into onPostExceute() and call the content for New Activty
Hope this could help...
I think it's better for you to use TreeMap instead of HashMap, which sorts data automatically everytime you mutate it. Therefore you won't have to sort your data before start another activity, you just pass it and that's all.
Also for using it you have to implement Comparable interface in your class which represents value of Map.
You can also read about TreeMap class there:
http://docs.oracle.com/javase/7/docs/api/java/util/TreeMap.html
I am not fully understanding what the synchronization block is doing nor why it is necessary.
Can someone explain in a "synchronizing for dummies" kind of way?
In a book I am reading, the author tells me "The synchronization is necessary, since the members we manipulate within the
synchronized block could be manipulated in the onPause() method on the UI thread."
He creates an Object named stateChanged and instantiates it as a new object.
Then, in the synchronization block he uses the stateChanged object as the argument.
This whole thing is throwing me off and I do not like to move on until I have a pretty good understanding of what is going on.
The classic example is: Imagine you have two threads of operation, and both of them reference the same method:
public void addToGlobalVar(int y) {
int x = globalVar; //what if a thread stops right after this line?
x += y;
globalVar = y;
}
where globalVar is some other predefined number that this method can interact with and set. Lets say globalVar is 50.
Threads get computing time on a somewhat arbitrary basis, so you never fully know the precise nanosecond one stops and the other gets CPU time.
In this example, if you launched an AsyncTask in addition to the UI thread, and both at some point use addToGlobalVar(10), what can happen is that one thread might be interrupted at line 2 of that code block. If the other thread goes through while that one is sleeping, it will successfully set globalVar to 60. But when the other one wakes up, it still thinks x = 50, and its going to then set it to 60. So in essence you just made 50+10+10 = 60. Hopefully you can see how this becomes a problem.
You can fix this simple example by making the calculation atomic (skip declaring x, 1 line, all calcs done) or if the logic wasn't able to be condensed to 1 line, you make a block of code atomic by using synchronized.
The book to read is Java Concurrency in Practice.
You should really just segregate this idea from Android, although your code is going to be running on Dalvik this is a Java concept. Not an Android one.
The synchronized block takes an object as a parameter, any object, and when flow enters the body of the synchronized block, any other thread that runs in to a synchronized block with the same instance (object) as the parameter has to wait for the previous one to complete. That's a very basic description.
This is an entire sub-field of computer science and without serious study you will probably not understand it.
You have to fully understand it before you use it. It is standard android synchronization using object-oriented monitors. You have to understand it to write multi-threaded programs, however it is somehow dated (better use java.util.concurrent for anything thread/synchronisation related instead).
Anyhow - you need to know what it is about - read the related java tutorial part:
http://download.oracle.com/javase/tutorial/essential/concurrency/sync.html