I am writing an Android application that has to download quite a lot of image files; the previous dev wrote it using various HttpClient type classes. These give no progress information whatever, and if the download fails part-way through there is no way to recover the missing bits (as far as I can find out).
We want to be able to report progress to the user, particularly if it is slow, and we want to be able to resume downloads, so I reimplemented this using HttpUrlConnection. It works fine single-threaded, but not multithreaded: I don't know what happens exactly but the images are getting corrupted. Android says that instances of this are indeed not thread safe.
As far as I can tell this means we have to choose between multithreaded downloads (which my colleague reports are slightly faster) and the ability to resume. Is there any way to get both on Android, short of implementing my own, thread-safe HTTP connection class?
Two things come to mind. The AsyncTask class (see: Painless Threading) is built for this sort of thing, and the new DownloadManager class was developed as a rather robust method that restarts if necessary, persists through device restarts, etc. Obviously it really depends on your situation, but give those a look and see if they're something you need.
Related
I'm working on a drag and drop app builder. The concept is simple: users can build their apps visually, then the app's settings get turned into a configuration file which will be used by the app to decide how to construct itself (which views should be shown, how should the navigation look like, etc.)
My main concern is once the users download the apk (or ipa) file, they can decompile it, change things in the configuration file and re-compile/re-sign it to be published as a brand new app.
I was thinking about putting part of the logic on server side but that would introduce me the following problems:
If 1000 people built and published an app with my software, and each app sends only 10,000 daily requests to my server, that's already 10,000,000 requests per day, which would be pretty expensive.
If my server is down for any reason, I will have a lot of angry users coming at me.
Got any ideas?
There is no exact way of stopping decompilation/reverse engineering process of android app or apk !
But there Some chances to reduce the scope of code visiblity after decompilation/reverse engineering process !
Here are some habits I am sharing
1) Put important code on a Server : You may rely on remote procedure calls to a well protected server. This reduces the chance of your codes being stolen as the code will always remain on the server and nothing other than the results can be seen.
2) Debugger Detection Techniques : Insted of using the hard coated values or string use some formula or encryption methods which can help to hide the actual values
3) Write important parts of code in C/C++ :You can also write the important parts of your code in C/C++ and add them as a compiled library. While it can be disassembled into assembly code, reverse engineering a large library from assembly is extremely time-consuming. Java is easier to decompile in comparison to C/C++.
These are some key habits which are be taken care by good developer , You should also check out this answer as well !
Huh, I knew it wasn't possible to stop the decompilation/reverse engineering process on any android app. But, I thought maybe everything was possible! Like, perhaps something has changed since then, but no. Basically, I use the same steps as Nisarg Jani described. But, you have to pay some special attention to the C++ code. Any mistake will destroy everything that you have built to that moment. So, if you use a no-code desktop app builder, you should be aware of those "tips and tricks." Besides that, you should keep in mind that without the C++ code, you won't be able to do anything.
My customer raise a problem about our app which is the app is getting slower when using for long time, but our side cannot simulate the problem as we are not in their real working environment, we are not able to solve the problem before knowing the bug. anyone can help?
If it´s a issue that raises "by the passing of time", you should look for any task you might be running and repeating itself.
You should check the different types of functionalities you use.
For example, if your app it´s using a local database:
Look for unclosed cursors.
I/O work
If your are using animations:
Look for skipped frames
Complex view hierarchies
If using background tasks or threading:
I/O work
Unfinished threads
Increasing thread number
If using networking and Webservices:
Problems with your server database
Connection issues
Proxys
...
You could also use something like Firebase + Crashlytics to see if theres any warning raises but gets silently disposed.
Giving some more info about your app and what it does could be useful for elaborating more accurate solution.
A common source of slowing down apps is memory leaks.
on iOS what you can do is to activate Memory management flags on your target and keep a watch on the logs, you can also use Xcode Memory Graph and instruments leak tools to detect leaks.
on Android you can use tools like LeakCanary to be notified when leaks happens.
Once you have a leak detected you can inspect your code to identify the source and better manage memory.
#axierjhtjz mention lots of good starting points.
Does it occur on both iOS and Android, specific devices, vendors?
If it is mainly on a single platform (Android/iOS), on different devices and the main complaint is slowness over time, I would suspect the following:
Memory leak (maybe UI, fragments)
Data persistent data incremental over time or/and more IO operation over time.
If you unable to debug the problem on the customer site, I would suggest to add a remote real time monitoring capabilities over relevant parameters and logs.
A good tool we used in the past was TestFairy. maybe they have a free trial
I have been developing a much-revamped version of an earlier android application. So many additions and changes to the infrastructure, UI, and general organization were necessary that it was far easier to start from scratch with the new application and transplant some of the guts from the old one rather than trying to understand everything the previous developer wrote and incrementally perform smaller surgeries.
I have the source code from the previous developer, and it contains several activities, fragments, classes, etc. that I know likely are not being used in the final build. To make the transplant process as easy as possible, is there an easy way to find out which of the above components are simply not being used in the app?
A couple ideas that immediately come to mind are:
stepping through everything in a debugger and taking note of which components are used (this seems like a super inefficient and terribly tedious process)
add a log message to each component's onCreate/instantiation code and then run through the entire app (more efficient, but still a pain)
Is there an easy way to do this?
I'm trying to follow Android best practices, so in debug mode I turn all the following on:
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectAll().penaltyLog().build()); //detect and log all thread violations
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll().penaltyLog().build()); //detect and log all virtual machine violations
Android now yells at me when I try to use any sort of file access or SQL in the main (UI) thread. But I see so many recommendations to use file access and/or SQL in the main thread. For example, the main activity should load default preference values inside onCreate() in case they haven't been set yet:
PreferenceManager.setDefaultValues(context, resId, readAgain);
Oops---that results in a file access on the first application execution, because onCreate() is called on the UI thread. The only way around it I can see is to start a separate thread---which introduces a race condition with other UI code that might read the preferences and expect the default values to already be set.
Think also of services such as the DownloadManager. (Actually, it's so buggy that it's useless in real life, but let's pretend it works for a second.) If you queue up a download, you get an event (on the main thread) telling you a download has finished. To actually get information about that download (it only gives you a download ID), you have to query the DownloadManager---which involves a cursor, giving you an error if you have a strict policy turned on.
So what's the story---is it fine to access cursors in the main thread? Or is it a bad thing, and half the Android development team and Android book authors forgot about that?
The only way around it I can see is to start a separate thread---which introduces a race condition with other UI code that might read the preferences and expect the default values to already be set.
Then use an AsyncTask, putting the setDefaultValues() call in doInBackground() and the "other UI code that might read the preferences" in onPostExecute().
To actually get information about that download (it only gives you a download ID), you have to query the DownloadManager---which involves a cursor, giving you an error if you have a strict policy turned on.
So query the DownloadManager in a background thread.
So what's the story---is it fine to access cursors in the main thread?
That depends on your definition of "fine".
On Android 1.x and most 2.x devices, the filesystem used is YAFFS2, which basically serializes all disk access across all processes. The net effect is that while your code may appear sufficiently performant in isolation, it appears sluggish at times in production because of other things going on in the background (e.g., downloading new email).
While this is a bit less of an issue in Android 3.x and above (they switched to ext4), there's no question that flash I/O is still relatively slow -- it will just be a bit more predictably slow.
StrictMode is designed to point out where sluggishness may occur. It is up to you to determine which are benign and which are not. In an ideal world, you'd clean up them all; in an ideal world, I'd have hair.
Or is it a bad thing, and half the Android development team and Android book authors forgot about that?
It's always been a "bad thing".
I cannot speak for "half the Android development team". I presume that, early on, they expected developers to apply their existing development expertise to detect sluggish behavior -- this is not significantly different than performance issues in any other platform. Over time, they have been offering more patterns to steer developers in a positive path (e.g., the Loader framework), in addition to system-level changes (e.g., YAFFS2->ext4) to make this less of a problem. In part, they are trying to address places where Android introduces distinct performance-related challenges, such as the single-threaded UI.
Similarly, I cannot speak for all Android book authors. I certainly didn't focus on performance issues in early editions of my books, as I was focusing on Android features and functions. Over time, I have added more advice in these areas. I have also contributed open source code related to these topics. In 2012, I'll be making massive revisions to my books, and creating more open source projects, to continue addressing these issues. I suspect, given your tone, that I (and probably others) are complete failures in your eyes in this regard, and you are certainly welcome to your opinion.
I have a web application to be hosted on android device. I am currently using the emulator available with android sdk. My application will serve both static as well as dynamic data. I am currently using jetty version 6.1.22. I wanted to ask what will be a better option to be used.
1. Jetty webserver with stripped off code.
2. I-Jetty.
My application uses following features-
ResourceHandler to serve static resources.
A Generic servlet to serve synchronous data requests.
An extension to CometServlet to serve asynchronous data requests.
I am looking forward to following criteria for comparison.
Application size. Size of apk which will contain the code.
Memory and CPU usage under a maximum load of 30 requests/sec. These are short bursts which occur very few times in app-life cycle. The average load would be approximately 5 requests/sec.
Ease of maintenance. Including important upgrades of Jetty in application.
Any other side-effects which I probably am missing out at.
I too have been searching for information on embedding the i-Jetty server in an application. Like the original poster, I need to serve both static and dynamic resources. I found the following post to be a helpful start:
http://puregeekjoy.blogspot.com/2011/06/running-embedded-jetty-in-android-app.html
I notice that in searching for answers about embedding a web server in an Android app that many responders, rather than providing a helpful answer, chide the original poster for wanting to do such a thing "in a phone". They then proceed to give all the reasons not to. There are more Android devices out there than just phones. My project involves just such a device. Thanks for all the helpful answers on this and other sites that guided me in my efforts. I hope the link I provided helps other searchers.
There are good reasons for embedding a web server in your app. May not be the best way but you have to do it when Android ties your hands. An example is when you want to decrypt video on the fly at runtime and use the media player to play it. Android media player does not allow me to feed it an in-memory stream as would come from a decryption pipe.
In this case, one solution (help me think of others please!) is to embed a web server that would serve up the stream - because Android does accept a stream from a URL!!
The other solution would be port some native library over and write a JNI interface to it. Too much work and unstable at best.
The point is, there are valid enough reasons out there.
It you need to decrypt video or serve content, you might consider just writing a simple web server yourself that can specifically handle your application's needs without any bloat. Adding an existing web server or web container might be more than you need. It very much depends on your application's needs though.
I have a web application to be hosted
on android device.
Why? It won't be usable, except maybe on a WiFi LAN. It won't be able to run terribly long, because services cannot run forever. Etc.
Whatever technical problem you think you're solving by using a Web server on Android can be better solved by other means.
I wanted to ask what will be a better
option to be used. 1. Jetty webserver
with stripped off code. 2. I-Jetty.
Arguably "neither", not only due to the technical issues, but that Greg Wilkins (creator of Jetty) does not like Android much. Of the two, though, i-jetty is at least regularly tested on Android.
Memory and CPU usage under a maximum
load of 30 requests/sec. These are
short bursts which occur very few
times in app-life cycle. The average
load would be approximately 5
requests/sec.
While running, battery life will suck, because you are going to keep the CPU and WiFi running all of the time to support the Web server, let alone the load.