Related
Hi all,
I'm new to Android development, kind of a Java noob, but not to programming in general. I'm not looking for code examples, just theory or a basic 'how this is done' in Java/Android. I also hope this will become useful information for other developers heading down this path.
I've had some success creating my first Android app - I apologize for not going into details about the specifics of the app, as I plan to eventually sell it commercially on the market - the question should, however, be applicable to any application using this flow model.
My current goal for this application is to create a 'plugin' type system ( like those used in OpenHome and other apps that allow user-generated plugin-able content / functionality ), to allow for flexibility in both my own further component development, as well as eventually creating an open interface for other developers to use to extend the application.
Currently my application is laid out as follows:
Main UI class
- entry point to the application
- starts the service class to spawn 'spinners' ( data processors )
- presents the user with an (ideally) extendable interface to the service
- binds to the service class using AIDL
Service class
- presents an AIDL interface for communication from the UI process
- creates 'spinners' of various types based on user interaction that process data
- persistent, will run in background, new Main UI instances will connect to the running service and present the currently running spinners.
- extendable via an as-yet-unimplemented plugin interface to add new types of spinners
Spinner classes
- use a generic interface with a handfull of common methods to communicate with the Service class, bubbling up data to the UI interface.
- processes user defined data streams, outputs to a buffer/sink suppled by the Service
Assumptions I can make are:
- the plugin (Spinner) class will always implement / override a group of methods to present to the Service class; ie 'putData()', 'getStatus()', 'start()' and 'exit()'
- the plugin class should always return data to the Service class via a supplied/shared buffer ( short array, for example )
Where I'm stuck at the moment is exactly how to implement extendable classes without those classes being a part of the current code base package. More simply, how do I interface with these classes without knowing their names, methods, etc?
As mentioned, I'm new to Java so I may just be overlooking an already implemented class that handles this interaction. If that is the case, I'd be happy for anyone to tell me to shut up and read the docs, if you can point me at the proper docs
What I really don't want to do is create a 'plugin language' for these external bits, as I feel this could hamper development of fast/functional plugins vs. those written as native Java classes. This would also expose potential security issues, as I'd need to create a public interface to the Service class for these applications to link to. I'd prefer if execution of the plugins remained private / internal to the 'main' application.
I'm already using an AIDL interface between the UI class and the Service class - it would potentially be possible to use further AIDL interfaces into each plugin, but from my romp-through-the-park implementing the UI -> Server communication in this way, I find it cumbersome and difficult to pass any kind of complex data sets/controls. And I'm still unsure how the Service class would actually implement these without inheriting the interface directly.
I've poked around Intents in Android, but I'm having trouble wrapping my head around them/what they're for - it seems it might be possible to inherit the plugins that define themselves as sinks for my applications specific Intent type, but I'm lost in the details of how this works exactly, or if it would even be a viable path for what I'm trying to do. Can new Intents even be introduced into Android?
I apologize for the long-winded explanation of what boils down to a simple question:
How can I implement a 'plugin' interface in my application to allow myself and other developers to extend my app through their own classes?
I've been a Java developer for 10 years or so.
From what I understand the "Android" way, would be intents. I'm still working on wrapping my brain around them too.
However, the "Java" way would be to define an interface (or several) for the plug-in(s) to implement. Then use reflection to identify classes in the classpath that implement that interface.
There are some advanced techniques using custom class-loaders, but researching reflection should get you started; if you choose to go that route.
Thanks for the quick response, I'll take a look at the reflection implementation.
Intents do seem to be the 'way to go' for inter-application communication in Android the more I read about it though - if I can figure out how to pull in plugins which specify my applications 'Intent' dynamically. Intents seem to work really well for spawning a 'dumb instance' of an application - like the browser when clicking a link in another app - when your application doesn't want to deal with that data locally.
Seems a bit more difficult to wrap them around a bi-directional interface between the service and the external plugin application. If anyone's got experience with this kind of thing I'd definitely appreciate prodding in the right direction. Documentation on Intents is confusing at best.
Hello XDA, I'm trying to write (what I believe to be) a simple app; a calculator with storage buttons. I've gotten the basic layout and initialized the core components. Yet, when I add on-click listeners, there's a force quit when testing. Attached is the Java class and xml. I've tried very hard to figure out what it is; I've even tried simply putting a println statement in the on-click listener. It doesn't even do THAT
Also, if there's anything (AT ALL) that you could criticize me on in terms of code organization, standards, etc. PLEASE let me know. I'm a newbie, and it's better to kick bad coding habits before they grow strong!
Thanks in advance, guys. I know it's annoying to debug others code, especially beginners, but I don't think it'll take much time at all, and I'd like to think I'm a relatively organized beginner
So I found out what it was; EditText doesn't accept ints or doubles as parameters. There's got to be an easier way of doing this, though. Is there any calculator-window-type objects that will store ints and/or (preferrably or) doubles? It's doable, but highly annoying to cast everything to a string and then parse it back to a numerical data type to perform operations on it.
Hi there, i'm new to developing Android Apps, so i have some questions.
1. I know that always have a chance of breaking security on computer world
2. Whats the most secure method to generate a UniqueID? because my app needs to work on china tablets, original tablets, cellphones, hacked phones, etc. I need this for verification of paid things (wait, xda will have a free version ;o)
3. There is any way to encript the program without affecting the performance too much? I'm new to java and comming from C++, so there is any compaction, encrypt, etc? Because if anybody knows the NEW IDA will come with android support.
4. There is any HTML parser on java? Because i need to fetch a html page with httpclient and after i need to parse it to get content... the contect is dynamic (html table with N rows), so i need a parser... or there is any other way?
5. I know how to make a tabed interface, but how is the best way to know the app state? Like it:
App Start -> User Already Logged (Save on SQLite?) ?
Yes = Display app interface and unlock config menu (here is the tabed interface)
No = Display login interface and lock config menu (here is just a relative layout with login bnts)
Thanks in advance.
1: Number one is not a question.
2: Do you mean most secure possible, or most secure practical? Those concerns should be addressed. Most secure would be to have a courier bring the user one-time-pads for every session, but that's not very practical. That said, what is the nature of your ID? Depending on what you are using it for, I would think a few randomly generated bits from some user entered entropy (like touchpad event timing) should suffice.
3: Again, what is the nature of your need for encryption? Do you want to keep it from being decompiled and analysed? If so, you're pretty much out of luck as there is always a way for a dedicated hacker to disassemble the code that does the decryption unless you use some sort of challenge-handshaking algorithm to load the keys at runtime for every session from some secure source but that requires connectivity and user interaction which necessarily complicates the process.
4: The XML parsers available as part of the Android SDK do a pretty good job of parsing HTML if it is clean compliant HTM> See, i.e. the Sax classes:
http://developer.android.com/reference/org/xml/sax/package-summary.html
5: You can use the API included preference classes to save state between sessions:
http://developer.android.com/reference/android/preference/package-summary.html
Note: for general application cryptography information, you still can't beat the venerated Applied Cryptography by Bruce Schneier.
Thanks for the answers.
I just wanna know how the most used programs like rom manager, power amp, titanium backup and whatsapp protect their paid versions, and how they validate it.
Another question that leaves on it is that some programs have a dedicated paid version, and some have just a key that you download and unlock the free version, how they did it? They just check if key is installed assuming that it was downloaded from market?
My uses is just for two reasons:
1.) protect my app as possible from newbie crackers
2.) transmit user information with a secure method to my server. Its important because my app will be used on open networks.
As for UniqueID generating, i just wanna a "unique world global super id" for each user of my app, and it will be installed on cellphones, tablets without phone, tv with android, and all of this.
Also, what to do if html is not well formated?
During recent development of my app (see my signature) I focused a lot on how to optimize the already working code further in order to make it smoother without loosing quality or using too much memory. Well I came across some mistakes I had made in my early days of developing Android so I figured it might help the beginners and intermediate developers. So here I collected my suggestion of common mistakes and best practices in Android. Let me start by making you familiar with a motto which you might know if you have developed Perl before.
TIMTOWTDI
There's more than one way to do it, in short TIMTOWTDI is a well known aspect of the Perl language, which aims at giving programmers the freedom to choose their way of doing things. It “doesn't try to tell the programmer how to program.” Well it does have various disadvantages such as possibly messy code and barely readable code, but it offers programmers to use their preferred style.
The only reason why I'm bringing this up here is because it helped me a lot to think that way, since TIMTOWTDI sometimes applies to Java as well and a way somebody else is preferring might not be better than your own way. But it is never bad to have a look at how others code the important tasks and sometimes the performance or readability gain is tremendous. So I'm not telling you to exactly use my way, but advice all beginners to perhaps rethink their code .
Tweaking Android Apps
The first step is always to look at what the awesome Android documentation says about performance, so I can more than advise you to read this straightforward article about what to do and not to do on Android. It covers some very important performance issues like the expensive object creation and method invocations. It is crucial to follow those basic rules while trying to develop fast Android apps. I will cover and further explain some of their suggestions here, but will try to also look at them from a developer's perspective who cares about readability and simplicity.
Now onto the code, let's start with some basic Java practices and then move on to some more Android specific styles and improvements.
Looping wisely
Often it doesn't matter if you write slow code and lose 1 or 2 milliseconds but especially in loops and everything that can be called once a frame you suddenly loose a lot of time. Thus it is crucial to especially pay attention to those repeated parts of your code like the onDraw() method in your custom view implementation (see last section) and start optimizing there. Let's take a look at what kinds of loops we have, the slowest first and the fastest ones towards the end:
while
The while loop is probably the first complex programming structure you learned, and just writing
Java:
success = false;
while (!success) {
trySomething();
}
is extremly readable but can potentially run forever or longer than you need it to. One aspect which is often overlooked is that the condition inside the parentheses will be checked on every run of the loop! So even a simple string.length() call can be optimized (if the String won't change) saving its length as an int and then using that in the condition block.
Its unpredictability and lack of possible tweaking done by the JIT makes the while loop a tool that needs caution but is sometimes crucial to complete the task. Just make sure you only use the while loop if there is no way to predict when your condition is false. For almost all other cases, you can do some calculations and use one of the iteration loops:
for (traditional)
This one is widely used like this:
Java:
for (int i=0; i<getSize(); i++) {
doSomethingWithIndex(i);
}
Even though this is more predictable, consider how the program will run: Before every execution of the block, the condition i<getSize() has to be checked, so getSize() is called (and an Android, method calls are expensive!). You could now think, alright, we'll just cache our size upfront like we did with in our while loop, but examine the following fast example of iterating through an array:
Java:
for (int i=getSize()-1; i>=0; i--) {
array[i] = getNewValue(i);
}
The trick is starting at the last value and then iterating backwards until 0 is reached. This may not work at all times, where the order of the blocks may be important or it is redundant due to having a fixed end value, but it saves both method calls and memory usage needed to get the last value before going into the loop.
But that is hardly readable and you often have to rethink because of looping backwards, so we can do better can't we?
for (iterator-based: “foreach”)
Dealing with an array, List or other collection of data you can easily do something for every part in that collection using the foreach loop:
Java:
for (Object item : objects) {
doSomething(item);
}
That is the fastest way you can iterate through any kind of iterable collection because it can be heavily optimized by the compiler and is also simplistic and readable. The only problem here is that you don't have the index of the item you're getting and you can't write data to the collection. To accomplish that one of the slower for loops must be used.
Keywords do matter
This is a minor one that is overlooked often. Beginners in Java mostly don't use keywords and access modifiers like “private”, “public”, or “final”. That is fine since we all love simplistic code don't we? And an honest word, if you don't write a library or work on your code with a big team, you don't have to know much about the access modifiers, but if you want to, there is always the Java documentation. But the “final” identifier is actually pretty important to both the ones reading the code and also the compiler, since it can just insert its value into the references. That means, that whenever you declare an instance variable, think about if it is likely to change or if you can declare it as final. Within methods, making use of the “final” keyword does not really change much for the compiler, but it sometimes helps you make a clearer design so you directly get a compiler warning whenever you're trying to change a final variable's value.
A side note on making “static” variables and fields – I wouldn't recommend that on Android unless you know what you're doing or you're using it together with “final”. A “static final” instance variable is the best way to declare constants in Android because the compiler can replace it fast and ART can replace it during the install of your app!
Strings are special
Let's talk about something that is fundamental to Java – the String object. Well it's not a real object since it is actually immutable. That means a String can only be created or collected by the garbage collector, it can't be changed (which is very important since object creation is god damn expensive in Android so it would make our apps pretty slow)! Wait, then what happens if I call one of the awesome methods in the String class like substring() or replace()? And here comes the downside: These methods have to create new Strings and the old one is collected by the garbage collector. While this might be totally alright if you're just parsing some basic user input, if you need to perform some heavy String operations like many substrings, a whole lot of unused garbage and overhead is created. This doesn't only mean that you are temporarily using a lot of memory, with the garbage collector needed to kick in it also affects your performance.
So how do we get around this problem? Luckily there is a Java class which can do almost the same as the default String implementation, the StringBuilder. This class will hold a char array with all the chars you had in your String. The class can take care of managing that array like initializing it with a default length of 16 and creating a larger array once you have more characters that would fit into it. Take a look at the constructors as well – with new StringBuilder(length) you can directly make that array as long as it needs to be and with new StringBuilder(string) the array is instantly filled with the string. The big advantage the StringBuilder is that it can modify the array instead of having to create new Strings every time. If you're finished with the heavy modifying, just call toString() to get the String back.
If you want to read more about it, here's a nice article.
Android-specific tips
Bundling is better than trundling
Let me explain this with an example: Let's say you are dealing with some data concerning persons so you are saving their name, age and gender. In any object oriented language like Java you would create a wrapper object holding that data:
Java:
public class Person {
private String name;
private int age;
private boolean isMale;
public Person (String name, int age, boolean isMale) {
this.name = name;
this.age = age;
this.isMale = isMale;
}
// additional getters and setters go here.
}
Of course you could do that in Android as well, but you will encounter this problem: What if you need to save your Person array or need to pass a specific Person to another activity? Well, you have a few options available:
You could override the toString() method in Person so it contains all its data and parse your array into a String array manually. Then another constructor will be needed to get the data back from the String using our beloved String operations. But there is still the problem that when you want to add data to the person like height later, you have to reconsider the toString() method and it's constructor counterpart.
Alternatively, wanting to integrate it better into the system, you might want to implement Parcelable in the Person class. That way you can directly put person extras to your Intent or save it to SharedPreferences. But that seems like more work if you want only a simple container for your data. Once you need have a more complex class it might be advisable to make it Parcelable (perhaps using the Android Studio plugin, thanks @nikwen), but let's start with an easier apporach here.
This is how I do it: I use a Bundle instead of a person class to store all the needed data. The Bundle class already implements Parcelable and and simplifies adding data for you. What is more, you are probably already familiar with it since you get one calling getExtras() on the starting Intent of your activity! Now back to the example, this is how it would be done:
To not get confused about all the keys you need, let's create a class containing some static final keys:
Java:
public class Person {
public static final String NAME = “person_name”; // will contain a String
public static final String AGE = “person_age”; // will contain an int
public static final String ISMALE = “person_ismale”; // will contain a boolean
}
While this is only needed for consistent keys, here is how you would create the Person:
Java:
public Bundle getPerson(String name, int age, boolean isMale) {
Bundle person = new Bundle();
person.putString(Person.NAME, name);
person.putInt(Person.AGE, age);
person.putBoolean(Person.ISMALE, isMale);
return person;
}
Similarly, you can get one or more stored values of the Bundle using one of the person.get...() methods. Furthermore, instead of creating an array of Persons you can now create a Bundle of persons using bundle.putBundle()! You just need to find the right key-scheme, here you could either provide an id for each person or just use their names as key (although the key array has to be passed seperately). And what do we get from all this? Well we can now just call intent.putBundleExtra(person) and voilà, we've passed it to another app component.
Resourcing is not outsourcing
One of Android's big advantages is its exceptional resource system. The fact that all your Strings and values are saved in a separate xml file makes your app not only easier to translate, but also keeps your code cleaner and lets you have a complete overview of what amount of constants you use. But you can go further than that. The resources allow for entirely different configurations depending on screen size, resolution, orientation, location and api-level! To learn more about how this can be done, head over to the Android devoper guides.
One thing I wanted to highlight is that it used to be quite hard to make a consistent interface and still support Android 2.1 and above. That is not the case any more since we now the the continuously improving AppCompat library. It is even useful for apps targeting only ICS and above because it contains bugfixes and improvements for those versions as well. Using this library is the best way to get the holo theme and its ActionBar in your app, although if you could also try ActionBarSherlock to accomplish the latter.
Click to expand...
Click to collapse
Think D.I.P
So what's this strange thing they call dip? And why do we even bother using it, we have had pixels (pix) since the beginning of programming. First things first, try to avoid pixels on Android. On almost every other platform using the smallest unit that's available is a great thing in layouts, but not so much on Android where apps can run on devices as small as a smartwatch up to 2k tablets. The problem is that you can't be sure if a single pixel is as small it can barely be seen or as large as a few millimeters. That is why we have the standard-sized density-independent-pixels (dip or dp in short) where 48 dips are roughly equivalent to 9mm, the convenient size of a touchable area (e.g. a Button). Great, then how many dips is my screen wide/high? That is not an easy question since it varies as well. Phones usually have around 320dips (at the smallest width) but larger screens can fit more so on tablets you have 600dips or more. Try to understand this documentation and don't be confused with the abbreviations dp, dip and DPI – dp and dip are the same and DPI is dots per inch (similar to pixels per inch), the screen density!
The reason why I'm bringing this up here is advice you to understand and always think in dips, never in pixels. Even on a Canvas, where there is only methods for pixels, don't think “ok I draw my text 20 pixels from the left edge and 50 from the top so canvas.drawText(“text”, 20, 50, myPaint);”. Start to think in dips: “I have to draw it 16dip from the left edge and 24dip from the top!” But how to convert it to pixels so it can be actually drawn onto the Canvas? It really is a shame there is no method in the Context class to directly convert dip to pixels, so here's the one I use:
Java:
private DisplayMetrics displayMetrics;
/**
* Converts a given dip (density independent pixel) value to its corresponding pixel value.
* @param dips The dip value to convert, as float.
* @return The pixel value, as int.
*/
private int dipToPix(float dips) {
if(displayMetrics == null)
displayMetrics = getResources().getDisplayMetrics();
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dips, displayMetrics);
}
And a side note on sp, that is the scale-independent text size. Try to use it as far as you can, for instance in layout resources. But just in case of needing the actual size, use the same method because sp is computed almost the same as dip.
Hyperthreading is not that complex
An app's UI (or “main”) thread is its beating heart, and we don't want to slow down what's powering us if there are other options available, right? If you don't follow the rule of not performing any time consuming tasks in the default thread you'll end up with what all developers fear: The “App is Not Responding” dialog – in short ANR. When users see this, they can get really mad, from just force closing your app and uninstalls to 1-star ratings everything is to be expected. Because it is crucial to know about Threads (and Processes), carefully read the guide in the Android docs about it, pay special attention to the two simple rules in Android threading:
1. Do not block the UI thread
2. Do not access the Android UI toolkit from outside the UI thread
Click to expand...
Click to collapse
Let's take a look at the first one, what are you going to do instead if you need to accomplish an expensive task like web requests, complex calculations, Bitmap operations, database queries and I/O management?
Well the answer is not as simple as it may seem since it depends on what and how often you will be doing that task. A task that is performed once per activity launch is almost always wrapped into an AsyncTask, a class which is heavily optimized and integrated into the system. If you know how it works it is a very powerful tool since it does most of the heavy lifting for you, so let me show you how to do it:
You start by extending the AsyncTask class like so:
Java:
private class MyAsyncTask extends AsyncTask<Param, Progress, Result> { //...
Usual stuff, except for the weird <Param, Progress, Result> thing. It is actually not that hard, these are all just type declarations of variables your methods want to use. Thus, the first one is the type of starting parameter you want. Think of it as if you wrote your task in a separate method without access to any instance variables, what data would it need to work (what params would you pass to it in the parentheses). The second one is actually often unused and is needed if you want to return a var indicating progress on the task so it can be published e.g. in a ProgressBar. Lastly, Result is (you may have guessed it) the type of variable you want your task to return, to be published in the UI as well. A typical configuration would be <Uri, Integer, String> for a task reading a file. Note that these have to be objects, so for primitives you'd have to use their respective Java classes like Integer or Double. But that also means that a Bundle can be used as well so we know how to pass multiple parameters now! And there is another way as well, look at the overridden methods:
Java:
protected Long doInBackground(Uri... uris) {
// do your expensive work here, it runs on a separate thread!
}
protected void onProgressUpdate(Integer... progress) {
}
You'll notice the three dots after Uri and Integer. To keep it simple, treat it as an array, so to access your value call uris[0] and progress[0], respectively. The reason for it being an array is that you can start the same AsyncTask with multiple parameters of the same task:
Java:
new MyAsyncTask().execute(uri1, uri2, uri3, uri4);
This is extremely useful in this case to read multiple files at the same time (don't be confused with the configuration in <> above, the param(s) passed to execute() are joined together in the Param array).
A side note on progress here, if you want to publish progress during your doInBackground(), just call publishProgress(Progress) and override onProgressUpdate() to publish the changes in the UI. Similarly with onPostExecute(), you'll probably want to override that method as well to show your awesome result to the user.
What you need to keep in mind is how AsyncTask is handled internally, read the section “The 4 steps” in the AsyncTask documentation carefully. In fact, doInBackground() is method you need to think about the most since it is encapsulated in a separate thread with no access to the UI or methods in your activity.
Because AsyncTask is limited to one operation and should only run up to a few seconds, there are a couple of other ways to do tasks in the background like a second Thread and helpers such as Handlers. The Handlers are needed to access the UI from the worker threads, still following the second rule above. If you want to read more here's an awesome Vogella tutorial about it.
Fragment-tation
This next one is really a good style of development and can save a lot of work if you provide layouts for both phones and tablets (which you definitely should). The basic theme of using Fragments is to follow the divide and conquer technique, which dates back to ancient time in Babylonia. Thus, the idea is to have one large problem (a user interface and its data for both tablets and smartphones) and split it into multiple simpler ones (in this case having one or more Fragments for each screen on phones). Especially in multi-pane layouts, for instance in the settings app, Fragments are a wonderful tool to avoid the use of two different activities, one for phones and one for tablets. The steps to implement them in your app are pretty simple and there are already some neat guides like the one in the documentation and Vogella's one. An additional use-case for Fragments is to retain an AsyncTask when rotating the screen. You would create a Fragment without layout in the UI and call setRetainInstance() on it. Any expensive AsyncTask can then be started inside that Fragment and is not stopped when the activity is recreated during an orientation change.
Memory-zing is unneeded
But it is not only performance, layout and style which can be improved, think about memory usage for a second. It goes hand in hand with performance since an app which consumes unnecessary memory (garbage) will be slowed down by the garbage collector (GC) thrown in from the system, trying heavily to free some RAM. On Android this is extremely important, since a garbage collector running intensely on a single or dual core processor can really slow down the device's performance. That is also why method calls and object creation are so expensive and have to be used with caution – the overhead they produce bumps up the memory usage. And there is one specific case where you can really have a problem with your memory, a so-called memory leak. What this means is that some part of your app is holding on to a very large object like a Resources or database one or even a whole Activity or Fragment. The problem is that the GC can only collect objects which aren't referenced from an active part of your app so this means it can't be collected and ends up blocking all your available memory. Such a leak is something you want to avoid at all times and there are some awesome tools to find out if you have one. All you need to know about that and memory optimizations in general is covered in this amazing I/O talk, so I advice you to watch that!
Most of the time there is no real need for reducing method calls and object creation because the GC is fast enough. But there is one step where it is crucial to avoid it, methods which are called on every redraw like the onDraw() method of a View, which I'll cover in the following.
Optimizing performance? onDraw!
In your custom views the most important method to think about is the onDraw() method since that is where everything that is visible to the user is rendered. A lot can be gained (or lost) in that crucial step, so try to follow the performance guidelines posted earlier as close as possible. Especially, pay attention to the object creation, creating a few objects in onDraw() might not seem expensive, but the memory footprint and the garbage collector usage will be tremendous. When drawing on a Canvas for instance, a common pattern would be to check if the paint instance variable is null before drawing:
Java:
if(paint == null) {
paint = new Paint();
paint.setColor(drawingColor); // ...
}
That code would typically be placed in the surfaceCreated(), but could also be in the onDraw() if you are lazy and want to keep it in one place. . While object creation is not the only thing you can improve performance-wise, just try to apply the aspects I wrote about in the beginning, especially those loops!
One thing I have to point out about performance before moving on to some links that might help you is that before trying to optimize your app in some arbitrary way (and totally destroying readability) measure upfront. That means use the tools mentioned in this great I/O talk covering graphics and performance to get a sense whether your app is really driving close to that 16 millisecond threshold to get the desired 60 frames. Additionally, it might be a good idea to not only test it on the high end devices (#Nexus5) but also those with a high “resolution/processing” value such as the first tablets with 1080p resolution. Thus, only start tweaking performance if you know you take too much time, then try to nail down the time consuming methods. And always try to improve readability and simplicity, not only for us when posting pieces of your code here but also for yourself: it helps getting into the flow if you see that your code is readable and nice .
Additional resources
If you can spare some time and want to know more about how to build awesome apps and UIs, check out the Android sessions at Google I/O 13, especially the Android UI design talk and the Android Protips 3 (but the first and second Protips were great as well as the beginner's talk from 2010). There is also the Android developers blog and the Vogella tutorials. As usual, the Android developers page is always a great resource and Google is still your friend (use “android dev” together with your question to get better results). For more info about general Java performance improvements, I found this nice pdf outlining how you can improve your code even further.
Click to expand...
Click to collapse
</guide>
Anyway, that's about it. It has really become a way too long collection of links and videos so I hope it was useful and perhaps made you rethink your code . If you've got any comments or suggestions feel free to post them here, helps a lot.
This guide was featured on the portal on February 4th (thanks eagleeyetom!)
To be continued...
One Thanks isn't enough!
Great writeup! Thanks!
Wow man such a good information muchly appreciated great job!
Sent from my Nexus 4 using Tapatalk
Wow, great collection of tips and tricks. Much appreciated!!
Handy tips
awesome job dude.was really helpful!!!!!:good:
Great article! Please keep going. :good:
Simply awesome...great work.
Sent from my SAMSUNG-SGH-T989 using Tapatalk
Thanks for this great writeup! The android specific tips are really interesting.
Great guide (again). :good:
Just one thing I want to add: I still prefer wrapper classes which implement Parcelable. In fact, it's not that difficult and you should be able to do it in a few minutes. Have a look at the example code here: http://developer.android.com/reference/android/os/Parcelable.html That's it.
I've also found an IntelliJ plugin for that purpose (but I haven't tried it yet): https://github.com/mcharmas/android-parcelable-intellij-plugin
That wasn't meant to degrade your work though. It's an amazing guide.
nikwen said:
Great guide (again). :good:
Just one thing I want to add: I still prefer wrapper classes which implement Parcelable. In fact, it's not that difficult and you should be able to do it in a few minutes. Have a look at the example code here: http://developer.android.com/reference/android/os/Parcelable.html That's it.
I've also found an IntelliJ plugin for that purpose (but I haven't tried it yet): https://github.com/mcharmas/android-parcelable-intellij-plugin
That wasn't meant to degrade your work though. It's an amazing guide.
Click to expand...
Click to collapse
Good point and thanks!
Having a closer look at it, implementing Parcelable is not that much work and it would definetely be the more advanced way. Bundle is basically just another layer that makes things a bit easier for the start (and no typecasting) and I found that it can really shine with a singleton class holding the keys and the getters and setters (which have an additional param, the Bundle). For a beginner who just wants to save some values (possibly keeping the keys in the activity or even hardcoded) using the Bundle is a lot easier. Yet again, TIMTOWTDI
Thank you!
Hey Simplicity, after few years there is something you would change? Maybe dagger2, kotlin, rxjava changed the game, as really open question what do you think about?
The question might be a bit off topic, i am working on a root app development but i am pretty confused that how should i get the busbox commands to run on button press, i have given the path and everything but how am i supposed to create a busbox file in data/data/package/files.
This part is confusing me I am not able to create that file, should i keep it in res while creating the app ? And also one last question, from where can i get that busbox file with all its command. Please help, I'm sorry if this is the wrong forum I'm new to posting questions and also to app development .
Hi guys, could you tell me how to open file for writing in the phone app LocalStorage for the non-unlocked handset (regular app for store)?
Code below doesn't work
Code:
FILE *tmp;
auto tmpPath = Windows::Storage::ApplicationData::Current->LocalFolder->Path + "\\tmp.txt";
auto tmpErr = _wfopen_s(&tmp, tmpPath->Data(), L"w");
Any suggestions?
Try looking though msdn articles. I found it somewhere in there. But I have forgotten it now.
Sent from Board Express on my Nokia Lumia 1020. Best phone ever!!
Note to noobs: DON'T PM ME WITH QUESTIONS. POST IN THE FORUMS. THAT'S WHAT THEY ARE HERE FOR!
@wcomhelp, please keep your rtfm advices for yourself, OK? I'm not a noob and of course I've searched msdn, google, codeplex, github etc. and so on before posting here. If you don't know how, much better be silent (like others who read this post but have no idea what I'm talking about)
I've tried a few possible methods including ugly "MS-way" with task & lambda syntax (see below) but nothing worked as it should be (code below works if no file exist and fails if file already exist - CreationCollisionOption::ReplaceExisting options is not worked/not implemented/buggy/billgates_knows_only ).
Code:
auto folder = Windows::Storage::ApplicationData::Current->LocalFolder;
Concurrency::task<Windows::Storage::StorageFile^> createFileOp(
folder->CreateFileAsync(CONFIG_FILE_NAME, Windows::Storage::CreationCollisionOption::ReplaceExisting));
createFileOp.then([=](Windows::Storage::StorageFile^ file)
{
return file->OpenAsync(Windows::Storage::FileAccessMode::ReadWrite);
})
.then([=](Windows::Storage::Streams::IRandomAccessStream^ stream)
{
auto outputStream = stream->GetOutputStreamAt(0);
auto dataWriter = ref new Windows::Storage::Streams::DataWriter(outputStream);
// data save code skipped
return dataWriter->StoreAsync();
})
.wait();
BTW, I've used workaround, to save ported C++ app data to the LocalSettings instead of text file (as it was in original code).
"Doesn't work" doesn't give us a lot to go on, troubleshooting-wise. Can you tell us what error you get?
Only thing I see in the code that looks a little weird is that the
Code:
"\\tmp.txt"
part isn't explicitly a wide-character string, but I'd expect string concatenation to take care of that.
Also, out of curiosity, why libc functions instead of Win32? Obviously, the code you're writing here isn't intended for much portability...
@GoodDayToDie, there is no error code at all - standard POSIX functions returns NULL FILE, the ::GetLastError() also return 0.
I'm porting old C-style app to WinRT platform and don't care about portability (but the first post code - just a simplified example, nothing more).
POSIX (libc) functions works pretty well for reading only but not for writing - that's the problem...
As I said before, I resolved my issue by workaround but still curious why the POSIX calls fails for file writing in the app storage.
buuuuuuuuuuuuuuuuh
No need for lambdas
https://paoloseverini.wordpress.com/2014/04/22/async-await-in-c/
You may also want to rethink your strategy
You can't create files at arbitrary locations, so your method is kinda redundant. All the locations you are allowed to create and read files to/from are available through KnowFolders and ApplicationData classes. These return StorageFolders which in turn can create files with CreateFileAsync (used for both creating and opening existing files) and get files with GetFilesAsync ( I recommend against this one though) and similar methods.
@mcosmin222, could you please re-read my posts one more time? I'm not trying to create files at "arbitrary locations"; I wanna create/write simple text file at the app's local storage (which one should be available for reading/writing). And the problem not in the lambdas or task usage (yes, it looks ugly but it works as it supposed to be).
Could you provide a working example instead of words? And I'll be glad to say you "thanks a lot"; can't say now...
sensboston said:
@mcosmin222, could you please re-read my posts one more time? I'm not trying to create files at "arbitrary locations"; I wanna create/write simple text file at the app's local storage (which one should be available for reading/writing). And the main problem not in the task (async execution).
Could you provide a working example instead of words? And I'll be glad to say you "thanks a lot"; can't say now...
Click to expand...
Click to collapse
Sure, just gimmie a few hours till I can get near a compiler that is capable of doing that
Of course, no rush at all, take your time. It's not a showstopper for me now (actually, my workaround with AppSettings is more preferable way - at least for universal app and roaming settings) but the issue still has an "academic interest" and maybe will be useful in the next projects for porting old C/C++ code to WinRT.
sensboston said:
Of course, no rush at all, take your time. It's not a showstopper for me now (actually, my workaround with AppSettings is more preferable way - at least for universal app and roaming settings) but the issue still has an "academic interest" and maybe will be useful in the next projects for porting old C/C++ code to WinRT.
Click to expand...
Click to collapse
hi
in vs 2015
#include <pplawait.h>
Something of the like should work
Code:
WriteSomeFile() __resumable
{
auto local = ApplicationData::Current->LocalFolder;
auto file = __await local->CreateFileAsync("some file", CreationCollisionOption::eek:penIfExists);
__await FileIO::WriteTextAsync(file, "this is some text");
}
However, as of right now, in VS 2015 RC, you have a host of limitations when dealing with this, but I do not believe this will be of any issue to you.
Code:
Cannot use Windows Runtime (WinRT) types in the signature of resumable function and resumable function cannot be a member function in a WinRT class. (This is fixed, but didn't make it in time for RC release)
We may give a wrong diagnostic if return statement appears in resumable function prior to seeing an await expression or yield statement. (Workaround: restructure your code so that the first return happens after yield or await)
Compiling code with resumable functions may result in compilation errors or bad codegen if compiled with /ZI flag (Edit and Continue debugging)
Parameters of a resumable function may not be visible while debugging
Please see this link for additional details
http://blogs.msdn.com/b/vcblog/archive/2015/04/29/more-about-resumable-functions-in-c.aspx
you should also note that this works with native, standard C++ types.
@mcosmin222, looks like unbuffered writing works (i.e. without streams) fine but it still not an answer for my initial question
I'm curious why the standard POSIX libc writing operations are not working on the app's local storage (but reading from files works fine). Actually, it's all about porting old C/C++ code for WinRT; of course for the new app it's not a problem but re-writing old code to FileIO should be a huge pain in the ass. What I did: I've "mechanically" changed all libc formatted outputs from file to string, and use LocalSettings class (actually it's XML file) to store that string (I'm planning also change LocalSettings to RoamingSettings, to provide settings consistency between WP & desktop app).
P.S. <pplawait.h> is not available in my VS 2015 (release pro version) so I've tested by using lambda pattern.
OK, first things first, LIBC != POSIX! The POSIX way to do this would be to call the open() function and get back an int as an "fd" (file descriptor), which is of course not implemented on Windows Phone because Windows Phone is not a POSIX platform (you might find the Windows compatibility functions _open() and _wopen(), but I doubt it). You are attempting to use the standard C library functions, which are portable but implement kind of a lowest common denominator of functionality and are generally slightly slower than native APIs because they go through a portability wrapper.
Second, sorry to be all RTFM on you but you should really Read The Manual (or manpage, or, since this is Windows, the MSDN page)! Libc APIs set errno (include errno.h) and use different error values than Windows system error codes (or HRESULT codes, or NTSTATUS codes, or...). Error reporting in C is a mess. If you were calling CreateFile(), you would check GetLastError(), but since you're calling _wfopen(), you check errno (not a function).
@GoodDayToDie, _wfopen_s returns 0 (i.e. "no error") but tmp pointer receives also 0 (NULL) Could you explain why libc file functions are working for reading (at the app installation & local data folders of course) but not for writing? Any logical ("msdn based") explanation? Or you just... don't know, heh?
sensboston said:
@GoodDayToDie, _wfopen_s returns 0 (i.e. "no error") but tmp pointer receives also 0 (NULL) Could you explain why libc file functions are working for reading (at the app installation & local data folders of course) but not for writing? Any logical ("msdn based") explanation? Or you just... don't know, heh?
Click to expand...
Click to collapse
LIBC functions will most likely work just in debug mode. The moment you try to publish the app it will fail. You can do lots of crazy stuff on your developer device with basic C functions, but if you try publishing, it won't pass the marketplace verification.
Most C APIs are simply not supported, since they do not comply with the sandbox environment of the Windows Runtime.
The code I gave you is tested with VS 2015 RC. You should be able to include <pplawait.h> just fine, if you are targeting toolchains newer than November 2013.
mcosmin222 said:
The moment you try to publish the app it will fail. You can do lots of crazy stuff on your developer device with basic C functions, but if you try publishing, it won't pass the marketplace verification.
Click to expand...
Click to collapse
Hmm... Are you sure or it's just your assumption? My app is still under development but (just for test!) I've made store app package for WP and it passed local store verification I also uploaded package to the store (via browser) and it also passed. I don't have time to create all tiles and fill all fields to complete beta-submission (actually, I don't know how to mark app as beta in the new dashboard) but for me it looks like app don't have any problem and will pass store certification easily. And you may be sure - it uses A LOT of libc calls 'cause originally it was written for Linux (or kind of UX system)
sensboston said:
Hmm... Are you sure or it's just your assumption? My app is still under development but (just for test!) I've made store app package for WP and it passed local store verification I also uploaded package to the store (via browser) and it also passed. I don't have time to create all tiles and fill all fields to complete beta-submission (actually, I don't know how to mark app as beta in the new dashboard) but for me it looks like app don't have any problem and will pass store certification easily. And you may be sure - it uses A LOT of libc calls 'cause originally it was written for Linux (or kind of UX system)
Click to expand...
Click to collapse
Once usage reports get up to microsoft, you will be given a notice to fix the offending API (happened to be once). You are much better off using the platform specific tools: not only they are much faster, they are also much safer and you won't have problems later on.
You might get away with reading stuff (since reading is not that harmful), but you should be using the winRT APIs each time they are available.
Simply uploading your app to the marketplace just reruns the local tests in their cloud servers: once you submit the actual app (not beta, not tests) for consumers, it will be much more aggressively checked. This is because the store allows specific scenarios for distributing apps in close circles that may break the usual validation rules.
@mcosmin222, one more time: is it your assumptions or personal experience? I don't know how many apps you have in store (I do have a lot) but I never heard that you said. I've used C++ libraries with WP hacks in some of published apps but never had any problem with "aggressive checks". What I know: if you are using some "prohibited" calls, your app will not pass uploading to the store (uploading, not a certification).
P.S. I'll send you personally a link when I publish release Hope, you'll like it
sensboston said:
@mcosmin222, one more time: is it your assumptions or personal experience? I don't know how many apps you have in store (I do have a lot) but I never heard that you said. I've used C++ libraries with WP hacks in some of published apps but never had any problem with "aggressive checks". What I know: if you are using some "prohibited" calls, your app will not pass uploading to the store (uploading, not a certification).
P.S. I'll send you personally a link when I publish release Hope, you'll like it
Click to expand...
Click to collapse
By "hacking" you mean recompiling the code to fit the windows phone toolchain? if so, then you shouldn't have to worry about too many things.
but even so, calling stuff like fopen in locations other than local storage will get your app banned. Even if it makes past the first publication, you can get noticed weeks later or even months (yes, it did happen to me personally).
In most cases, calling C APIs that can potentially break the sandbox (like opening a file in doc library with fopen) will always fail the marketplace verification, eventually. If it hasn't happened to you yet, then you may have not been using such APIs.
No, my C++ code is not accessing other than approved locations but the app has a lot of libс (and of course other C/C++ libs) calls; I'm 99.9% sure it's legitimate and will be not a source of any problem. Otherwise what is the advantages of having C++ compiler?!
As far as I know, just some of API's are prohibited but you will notice it right after local store compatibility test run...
As for "hacks" I mean usage of undocumented ShellChromeAPI calls (including loading hack).
P.S. I've found why <pplawait.h> header is missing. Initially I've created solution with the 12.0 toolset but now I can't (or don't know how to) change it to 14. However creating the new empty universal solution in VS 2015 also gives me toolset 12 by default. What is the toolset 14 for? Windows 10?
sensboston said:
No, my C++ code is not accessing other than approved locations but the app has a lot of libс (and of course other C/C++ libs) calls; I'm 99.9% sure it's legitimate and will be not a source of any problem. Otherwise what is the advantages of having C++ compiler?!
As far as I know, just some of API's are prohibited but you will notice it right after local store compatibility test run...
As for "hacks" I mean usage of undocumented ShellChromeAPI calls (including loading hack).
P.S. I've found why <pplawait.h> header is missing. Initially I've created solution with the 12.0 toolset but now I can't (or don't know how to) change it to 14. However creating the new empty universal solution in VS 2015 also gives me toolset 12 by default. What is the toolset 14 for? Windows 10?
Click to expand...
Click to collapse
The advantage of C++ is the obvious versatility: the standard C++ APIs will work fine for you as long as you stay inside the sandbox (this means you can't access files even in locations that are outside of sandbox but you have permission to them, such as music library). You can use most classic C/C++ libraries without issues as long as you do the interface with the runtime broker yourself. That means using windows runtime APIs instead of classic C APIs when dealing with stuff such as file access, for example. This is a pretty extensive topic and It is rather difficult to explain it all with 100% accuracy, especially when there is lots of docs running around.
You also get deterministic memory management, which is huge in specific scenarios.
Long story short
You will be fine with standard C/C++ when using
any in-memory functions supported by the compiler (you can manipulate data types, string, mutex, etc).
File IO in isolated storage only (applicationData folder)
Threads (although you are better off using threadpool or the like, it is much easier and cleaner). You can also use futures, and std::this_thread.
You will have to use winRT replacement
File system access in any other location than application data (you must use the windows::storage APIs)
sockets, internet access and the like.
any hardware related thing: music&video playerback must be interfaced through winRT (although the underlying decoders can be classic C/C++), messing around with the device sensors.
Retrieving system properties (internet connection state etc)
cross process communications
communicating with other apps
There are also win32 equivalents
mutex, threading, fileIO (isolated storage only)
Media playback with custom rendering pipeline.
Basically, winRT functions as an abstraction layer between the hardware and your code. You can use classic C++ up to the point where you need to interact with the system in any way. At that point, system interaction must be done with winRT. This way, microsoft ensures a higher degree of stability and security for devices.
check this link out for more information on the toolchains. You should be able to use this in VS 2013 as well with windows 8 (this is a compiler feature, has nothing to do with supported platform)
https://paoloseverini.wordpress.com/2014/04/22/async-await-in-c/