Create New Thread - Android - java

I'm trying to implement a looper so I can create a thread for sending GPS coordinates to a database. I'm new to Java and this is all really confusing, but maybe you can help. The following class method is called by the main activity when a button is pressed. The method finds the GPS location and then sends it to a different class's method that sends the latitude and longitude (along with the user id) to a database. I'm having trouble with my app slowing down and freezing at times, so it appears I need to implement some way to create a new thread for this process. Any ideas. I'm a noob so be gentle. Here is my code:
public class LocationActivity extends Thread{
private LocationManager locManager;
private LocationListener locListener;
public void startLocation(Context context, String usr_id2)
{
final String usr = usr_id2;
//get a reference to the LocationManager
locManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
//checked to receive updates from the position
locListener = new LocationListener() {
public void onLocationChanged(Location location) {
SendActivity.send(location, usr);
}
public void onProviderDisabled(String provider){
//labelState.setText("Provider OFF");
}
public void onProviderEnabled(String provider){
//labelState.setText("Provider ON ");
}
public void onStatusChanged(String provider, int status, Bundle extras){
//Log.i("", "Provider Status: " + status);
}
};
Looper looper = null;
locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locListener, looper);
}
}
One other question, would I add the looper here or in the class that actually sends the information to the database? It uses HTTP Post to send to a PHP program that adds the info to a MySQL database.

I would be tempted to try a different tactic here. Android has a class called AsynTask which is written to ease the burden on developers of offloading work to be done on a thread.
AsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.
In terms of writing to the DB and sending data back to a server, I would look at using a Service, but remember that the only Service that doesn't natively run on the UI thread is the IntentService

You should consider using AsyncTask class for such operations, it's pretty easy to use and it provides a simple way of synchronizing with the UI thread. Here's a nice post about threading in Android, you can learn more about AsyncTask in the Android docs. Hope this helps.

You can't access the 'context' or any UI object from a custom thread. This is because these are made in the main UI thread and you can't access these objects from your thread.
Just as Martyn said, you need to create a AsyncTask or use Handlers to access the context/ui.
In your case, go for the AsyncTask

Related

Are there any downsides to using a static class with multiple static AsyncTasks?

I made a static class (NetworkUtils.java) with a few static AsyncTasks, each sending some data to server and retrieving a response.
It is working great (in a test environment) and it made the code very clean in the Activities:
NetworkUtils.SomeNetworkingTaskCallbackInterface callbacks =
new NetworkUtils.SomeNetworkingTaskCallbackInterface() {
#Override
public void onFinished(String result) {
}
#Override
public void onFailed() {
}
};
NetworkUtils.SomeNetworkingTask task = new NetworkUtils.SomeNetworkingTask(callbacks);
task.execute();
Now I am doing a little extra research if there is anything wrong with this approach. I've seen a lot of use-cases of nested static AsyncTasks, but I need them completely decoupled and modular, that's why I put them into a separate static class. I can't think of any downside. Can someone more experienced weigh in?
The only disadvantages I can think about is that you won't have any access to non static members of the parent class. If for example, your static Async Task object had an Activity parent class you wouldn't be able to call methods that require a context. That means you won't be able to start services, activities or broadcast events from the Async Task.
However, you could simply pass a context object to the static class to solve that. But then what happens when your Async Task takes long and your activity gets destroyed before it's onFinish is called? You're get an error as your context object is from a destroyed activity.

Should DialogFragment be called through AsyncTask class?

I read many guides but I'm still confused.
Somewhere I read that the "activity flow" should not be interrupted by a DialogFragment, so you should call DialogFragment inside a AsyncTask Class inside the Activity Class.
In other guides I saw DialogFragment being called from the Activity Class without using AsyncTask.
So my question is: should DialogFragment be called only through AsyncTask class?
This is the way I did so far; the Activity class code:
public class LunchActivity extends AppCompatActivity {
....
public void callDialog(){
class ShowInfoToUser extends AsyncTask<Bundle, Void, Bundle> {
...
#Override
protected Bundle doInBackground(Bundle... args) {
...
}
#Override
protected void onPostExecute(Bundle resultBundle) {
DialogFragment permissionDialogManager= permissionDialogManager.newInstance(messageBundle);
permissionDialogManager.show(activity.getSupportFragmentManager(), "Permission Dialog");
}
}
}
This is the class that extends DialogFragment:
public class PermissionDialogManager extends DialogFragment {
public static PermissionDialogManager newInstance(Bundle bundle) {
PermissionDialogManager frag = new PermissionDialogManager();
frag.setArguments(bundle);
return frag;
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
...
}
}
Thank you
The code inside AsyncTask's onPostExecute method execute in the UI Thread. In the example you have provided, there is not difference if you use AsynTask or not, because the code will be executed in the UI Thread.
Maybe in the example you have seen, they process some information in the AsyncTask's doInBackground method (that execute in separate thread) and later in the onPostExecute method they use the previous information to invoke the DialogFragment.
How to know when should you run code in the UI Thread?
Processes and Threads
When your app performs intensive work in response to user interaction, this single thread model can yield poor performance unless you implement your application properly. Specifically, if everything is happening in the UI thread, performing long operations such as network access or database queries will block the whole UI. When the thread is blocked, no events can be dispatched, including drawing events. From the user's perspective, the application appears to hang. Even worse, if the UI thread is blocked for more than a few seconds (about 5 seconds currently) the user is presented with the infamous "application not responding" (ANR) dialog. The user might then decide to quit your application and uninstall it if they are unhappy.
As the Dialog will interrupt the user, I see no reason to put it in an AsyncTask. The dialog is not supposed to take a huge amount of time to generate itself.

How can I update my Android SQLite database from a thread without access to the Context?

I am working on an Android app. One of the first things the app does upon starting is to launch a listening thread. This listening thread opens a UDP socket to another application on the tablet, and listens for that other application to send data. When my listening thread receives data, I want to store the data into the SQLite database, but I cannot figure out how to do that without access to my app's Context.
I have a database helper app:
public class DatabaseHelper extends SQLiteOpenHelper {
public DatabaseHelper(Context context){
super(context, "myAppDatabase.db", null, 1);
}
#Override
public void OnCreate(SQLiteDatabase db){
db.execSQL("CREATE TABLE ...");
}
#Override
public void OnUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
db.execSQL("DROP TABLE ...");
}
// my database CRUD queries
}
This DatabaseHelper class is the only place where I perform any CRUD operations on the database.
I start my thread from MainActivity:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState){
ListenerClass myListenerClass = new ListenerClass();
Thread listenerThread = new Thread(myListenerClass);
listenerThread.setName("My Listener Thread");
listenerThread.start();
}
}
And I have my listener class:
public class ListenerClass implements Runnable {
private volatile boolean run = true;
private DataProcessingClass myDataProcessingClass;
#Override
public void run(){
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
// Open UDP socket
// Listen for data
// Process the data
myDatagramSocket.receive(myDatagramPacket);
byte[] data = myDatagramPacket.getData();
myDataProcessingClass = new DataProcessingClass();
myDataProcessingClass.processData(data);
}
public void setRun(boolean run){
this.run = run;
}
}
When my listener thread receives data, it calls another class to process that data, and store it into the database. It works up until I try to store it into the database, because I do not have access to the app's Context.
Is there any way to write to the SQLite database without access to the app's Context? If not, how can I go about getting hold of the Context for this database write?
Unfortunately, I don't think you will be able to do this without an access to the Context.
The only advice I can give you in this direction is to introduce the Context as a dependency of the thread.
I would also like to point out a few other things, related to the architecture. Your approach would be totally valid for inter - app communication in the general case, but I think it's a bit suboptimal when it comes to Android.
There are a few ways in which you can leverage out - of - the - box components to do the heavy lifting for you. I would point you to the use of ContentProviders - they are ideal for sharing data between apps and will eliminate the need of a UDP connection, dealing with threads and will greatly simplify your app architecture.
Another alternative is to make use of the Intent mechanism - you can have App A send intents with binary data to App B. App B can handle those in Broadcast Receivers, which will give you access to a Context and the ability to invoke other components of your app, capable of persisting the resulting data.
The solution which I typically use is to add a constructor which takes a Context. In this particular case, you will need to add such a constructor to both ListenerClass and to DataProcessingClass. The ListenerClass constructor will pass the given Context to the DataProcessingClass constructor.
Alternatively, you can add a DataProcessingClass(Context) constructor as before but have a ListenerClass(DataProcessingClass) constructor instead. This allows someone else to initialize the DataProcessingClass object first so that ListenerClass doesn't have to worry about how it is initialized. Also, this allows you to go a step further and use dependency injection for initializing your objects. (Dependency injection is probably a more advanced topic than necessary for this question. I just want to mention it so you can research further if you are interested.)
You can subclass Application and provide a static method to get the app context:
public class MyApplication extends Application {
private static Context sContext;
public static Context getContext() {
return sContext;
}
#Override
public void onCreate() {
super.onCreate();
sContext = this;
}
}
When an app is launched, the system constructs theApplication instance and calls its onCreate() before creating any activities, services, or receivers (see the comments in the docs for Application.onCreate()). Activity code can thus rely on MyApplication.getContext() to always return a valid context.
If you use this approach, remember to also update the application name in your manifest:
<application
...
android:name="com.example.MyApplication" >

How to use runOnUiThread() or onPostExecute() to update the UI within a thread

I have a class ConnectionThread that extends Thread. I am passing the context to it's constructor and i want to invoke a method that enables and disables all the buttons on the UI. This method is in the same class - ConnectionThread. Also i want to popup a Toast in a try catch block in case the connection can't be established.
public ConnectionThread(Context context, BluetoothSocket bluetoothSocket,
Button connectButton, Button disconnectButton,
Button throttleUpButton, Button throttleDownButton,
Button moveForwardButton, Button moveBackwardButton,
Button moveLeftButton, Button moveRightButton, Button exitButton) {
My question is how can i use runOnUiThread() or onPostExecute() to do that?
onPostExecute()(only in Asynctask) runs already on UI thread so no need to create a runOnUiThread inside of it.. In other case if you are inside a thread or background task and want to update some views now you need to call the runOnUiThread because you are now leaving the main thread..
pass the activity instance to the contructor to call the main thread.
example:
activity.runOnUiThread(new Runnable() {
public void run() {
//code here
}
});
views all have the very handy post method that does the same as Activity.runOnUiThread:
connectButton.post(new Runnable() {
public void run() {
// TODO Update your UI here
}
});
If you really must use Thread, use AcyncTask. It's a thread + Android-specific thread lifecycle boilerplate:
class ConnectionThread extends AsyncTask<Argument, Integer, Result> {
protected Result doInBackground(Argument... args) {
du stuff here
return result;
}
protected void onProgressUpdate(Integer... progress) {
// called in UI thread
}
protected void onPostExecute(Result result) {
// called in UI thead
}
}
But honestly, that's a bad design decision. You must keep in mind that the activity can be destroyed at any time and running task may report back to invalid Activity, forcing you to manaully do the housekeeping: registering/unregistering listeners, keeping valid/invalid flags, stuff like that.
There are A LOT of libraries to do asynchronous tasks civilized way, such as:
RoboSpice: https://github.com/stephanenicolas/robospice
Official Loader API will save you tons of problems too.
Volley
DataDroid (obsolete, but still can be found in many projects)
Alternatively you can move your long-running tasks to a Service and keep worker threads there. Activity can bind to a Service and unbind from it, keeping your application logic decoupled from the UI.
Pushing all app logic into the `Activity is the major source of PITA in Android apps across the board. I have no idea why Google is promoting such bad practices. It looks nice and simple in tutorials (that's a PR move maybe?), but doing anything beyond hello-world ends up in endless Activity lifecycle debugging sessions.
TL;DR
Use RoboSpice, Loader or similar solution
Use Services
Forget about Thread, AsyncTask only in the simplest cases

BroadcastReceiver has onReceive() called unexpectedly

I have an app in which I want to perform lookup some data every, say, 15 mins. I have a service that I start with an alarm, but I also want to make sure that there is a network connection before I start looking.
To do this I think I should use a BroadcastReceiver to watch for changes to the network state. I have wrapped a broadcast receiver to help with this:
public abstract class NetworkMonitor extends BroadcastReceiver
{
boolean mDoingStuff;
public abstract void doStuff();
public NetworkMonitor()
{
mDoingStuff = false;
IntentFilter networkStateFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
MyApp.getContext().registerReceiver(this, networkStateFilter);
}
#Override
public void onReceive(Context context, Intent intent)
{
// network state changes, you can process it, information in intent
ConnectivityManager cn = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = ConnectivityManagerCompat.getNetworkInfoFromBroadcast(cn, intent);
// Only use Wifi Connections for updating this
if (info.isConnectedOrConnecting() && !mDoingStuff)
{
mDoingStuff = true;
doStuff();
}
}
}
I then use that in a service like:
public class WidgetUpdateService extends Service
{
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
// Build the async task to get the data
final MyAsyncTask mTask = new MyAsyncTask();
// Register an interest in when the network changes
new NetworkMonitor(false)
{
public void doStuff()
{
mTask.execute();
}
};
// Make sure that if we get shut down then we get started again correctly.
return START_REDELIVER_INTENT;
}
protected class MyAsyncTask extends AsyncTask<Void, Void, Void>
{
public MyAsyncTask()
{
}
#Override
protected Integer doInBackground(Void... arg0)
{
// do work
}
#Override
protected void onPostExecute(Integer result)
{
WidgetUpdateService.this.stopSelf();
}
#Override
protected void onCancelled(Integer result)
{
WidgetUpdateService.this.stopSelf();
}
}
}
Where MyAsyncTask is an inner class that will cause the service to stopSelf() when it has completed.
This kinda works but:
I'm getting (according to logcat) far more calls to NetworkMonitor.doStuff() than I would expect. It seems that even when the service has been stopped (after the async task has finished correctly) the NetworkMonitor instance is still being receiving intents about changes to the network state. Why is this?
Do I need to have a variable to store the NetworkMonitor() instance in the service, or can I just have an anonymous instance like this? Looking at the docs the BroadcastReceiver should clear itself up after onReceive() has finished.
Why do I need NetworkMonitor.mDoingStuff? I'm guessing that if I can work out why the NetworkMonitor is not clearing itself up after onReceive() has finished then I may not need it any more?
Is this a sensible way of doing this or am I asking for trouble?
Please let me know if you need any more info, I'll be happy to supply it.
This kinda works
It's ghastly code, IMHO.
It seems that even when the service has been stopped (after the async task has finished correctly) the NetworkMonitor instance is still being receiving intents about changes to the network state. Why is this?
Because you never unregister the receiver. It will keep going -- and leaking memory like a sieve -- until your process is terminated.
Do I need to have a variable to store the NetworkMonitor() instance in the service, or can I just have an anonymous instance like this?
You need to have an instance so you can unregister it later. Registration and unregistration of the receiver should be done by the service; your register-the-receiver-in-its-constructor is part of what makes your code ghastly IMHO.
Looking at the docs the BroadcastReceiver should clear itself up after onReceive() has finished
A manifest-registered BroadcastReceiver lives for a single broadcast. A BroadcastReceiver registered via registerReceiver() lives until unregisterReceiver().
Why do I need NetworkMonitor.mDoingStuff?
You have bigger problems.
Is this a sensible way of doing this
Not really.
First, you will crash on your second broadcast, as you cannot execute() an AsyncTask instance multiple times.
Second, see the aforementioned failing-to-unregister issues.
Third, if you want to have a service that does one thing, then goes away, use an IntentService.
So, let's roll all the way back to the top:
I have an app in which I want to perform lookup some data every, say, 15 mins. I have a service that I start with an alarm, but I also want to make sure that there is a network connection before I start looking.
The right way to do this is:
Have your AlarmManager event route to a BroadcastReceiver. This is particularly important if you are using a _WAKEUP alarm type, as such events are only reliable if you use a BroadcastReceiver PendingIntent.
In that BroadcastReceiver, in onReceive(), if you have a network connection, send a command to an IntentService to do the work (and, if you are using a _WAKEUP alarm type, consider my WakefulIntentService, so the device stay awake while you're doing this).
If, instead, there does not appear to be a network connection, have your BroadcastReceiver enable another manifest-registered BroadcastReceiver set up to watch for CONNECTIVITY_ACTION events -- use PackageManager and setComponentEnabledSetting() for this.
In the CONNECTIVITY_ACTION BroadcastReceiver, in onReceive(), if you determine that you now have a network connection, kick off your IntentService (same as what you would do from the AlarmManager receiver if you already had a connection).
In the IntentService/WakefulIntentService, do your work in onHandleIntent(). This already has a background thread and will already call stopSelf() when there is no more work to be done.
In the IntentService/WakefulIntentService, in onDestroy(), disable the CONNECTIVITY_ACTION BroadcastReceiver via PackageManager and setComponentEnabledSetting(), returning you to your original state.
This way:
You don't leak memory, as you are doing here.
You don't have to mess with threading code, as you are doing here.
You don't have to worry about whether or not your process gets kicked out of memory in between the alarm and gaining connectivity.
If connectivity is blocked for some time (e.g., airplane mode), you don't register N receivers and set up N AsyncTasks, as you are doing here. Instead, you will get control again whenever connectivity changes occur in the future after your alarm has gone off.

Categories