Sending an Activity to a non-Android class - android

I'm pretty much a noob when it comes to Android development. I have an Activity that has a method that pretty much just sets the text of a TextView to whatever text is provided as an argument. I have a second class, which is a Runnable, and I want to be able to give it the Activity (or obtain the Activity somehow), so it can call said method when it needs to.
This Runnable will eventually connect with a server, so it can update the application with information from the server. I've done client/server Java stuff before, so that's not the issue. I just need to figure out how to communicate between this Runnable and the Activity.
Originally, I was going to just pass the Activity itself in, but I read that it would create problems if I did. Instead, I was supposed to pass in an ApplicationContext via getApplicationContext(). I did that, but now I don't know what to do with the ApplicationContext. I tried casting it to the my Activity class, but the program just crashes.
How do I accomplish what I'm aiming at?

There are a few specific ways in Android to handle threading like AsyncTasks etc., you should read up on how to do 'painless' threading here. If it's just a one-off task where you connect to the server, get the value, set it in the TextView and then finish, I think an AsyncTask would be your best option. Continuing background processes are more suited to being services.

you can pass your activity to the constructor of your second Class like this :
public SecondClass(YourActivity _yourActivity){
this.activity = _yourActivity;
//do stuff
}
and in your Activity , you can instanciate your class like this :
SecondClass instance = new SecondClass(this);
NOTE : in your SecondClass , if you want to change the UI of your application , you can use the method runOnUiThread(Runnable);

Related

Activity without UI to write a maintainable code

What is the use of Activity without UI? I have a MainActivity where I feel the code is too long and I was thinking about possibly creating a separate Activity without UI for each task and call it in my Main Activity (or use a Headless Fragment maybe?) in order to keep my code maintainable. Is that a bad approach? How do you manage relatively long code in one Activity?
That's a bad idea. It makes sense to break an activity up into multiple classes if its too large/too complicated. If those pieces have a UI, that's basically a fragment. If they don't, they should be some other class. But there's no reason to make them Activities- they're just classes.
THere's very few places where it makes sense to have a headless Activity. Almost all of those places are where Android requires you to start a context but you're not sure which one to start up yet (for example a headless activity that does url routing that's too complex to put into the manifest).
There a lot of things wrong with your questions.
First... An Activity without UI, then doestn need to be an Activity.
Second, you must know what is a class and why we use classs.
Third, When you have long code, maybe your logic is bad, you can separate en in other class the code, example: Adapters, Helpers, Task, etc.... the same activity and code must give you and idea how separte correctly if you know the concepts, please, maybe if you post the code we can help you more.

Socket Architecture Between Multiple Activities

I am starting to write an application which uses a socket to communicate with another device. I am currently trying to design the architecture of the application. It will have multiple activities. My question is if I have a single socket instance that gets passed between activities, or is declared in a class which extends Application, how do I know when to close it unless I open and close it in each activity? - Although this would work I am unsure if it is the 'cleanest' method.
I don't think you will find another good way of doing what you want. I would create the object inside the application class or as a singleton. And maybe create a BaseActivity class which will get the reference in onCreate and release it on onDestroy. This class you would extend in every activity you want to use your object in.
I would also track the references inside the Singleton class that defines your "socket", meaning have a counter which is incremented on each get and decremented on each release call. when the counter gets to 0 you can close the socket or better post a runnable which will close it after a specific time if no new activities "get" the reference again.
I have done something similar in my library for handling runnable.
Check it out here:
BaseObservableThreadPoolService |
ThreadCountObserver

Is this the best way to implement AsyncTask? Or are there better ways?

I am trying to write a AsyncTask generic package. Till now, what I've done is call one activity from another send the instance in the Intent to that Activity. This activity is part of the AsyncTask which calls the AsyncLoader.execute() file. I am doing this so that I don't lose any data that the parent Activity sets on the layout.
The other way to do it would be to call the Intent and return the data from the AsyncActivity to the parent Activity. But, both of these methods are slower than implementing the AsyncTask in the parent activity.
But, that clutters up the code. Thus, is there a better way of implementing it?
It sounds like your tight-coupling between the activity and the AsyncTask is causing you issues that you're trying to overcome with a weird workaround.
In my experience the best way to design activities that need an AsyncTask is:
Keep your AsyncTask out of your activity, i.e. make a separate class
that extends AsyncTask. This allows you to reuse the AsyncTask
between multiple activities and make it easier to test.
If you need to return data back to your activity, use the listener and implement the listener on your activity. Then pass your listener to a class that creates the AsyncTask.
Passing of data between intents should be kept to a minimum, if you need to reuse the same AsyncTask from a separate activity you should follow the steps above and execute the task again. If you're going to be calling this through the lifecycle of the app, then consider using a service instead.

If AsyncTask is not an inner class... - some questions

1) I don't underestand why the samples of Android almost use AsyncTasks as private inner classes. I know it is convenient to make it inner class but it makes our class file longer and hard to read. ShelvesActivity of Shelves sample application have even 845 lines. Don't you think it is a bad design or bad construction?
2) If I make my ScanStorageTask external class, what do I have to pass to it? entire Activity or only used widgets?
Example: If I must use a WebView, a Button and a ProgressBar in ScanStorageTask.
I use this:
ScanStorageTask task = new ScanStorageTask(this); // "this" is activity reference, then get the webView, button, progressBar from it.
or this:
ScanStorageTask task = new ScanStorageTask(webView, button, progressBar);
There's nothing wrong with doing it externally, and it actually might be a better design. Passing UI elements around is the kind of tight coupling that can get you into trouble when you have a really large code base anyway.
Why not do it externally and use the "listener" pattern that the UI controls employ? Make your ScanStorageTask its own class, create an OnCompleteListener interface with an onComplete method, and pass that to your ScanStorageTask instance (expose a setOnCompleteListener method or something to that effect). Then, onPostExecute can just do this:
if(onCompleteListener != null)
onCompleteListener.onComplete(data);
That way, you define your UI updates inside your activity based on the data. It's better separation of concerns and will keep your lines of code per class down, as that seems to be what you'd prefer. If you don't already have this, make a class that represents the data you need to pass in and get out, and that's what you pass in to the task as a param to the execute method and what onPostExecute passes to onComplete.
Inner classes allow you to manipulate the UI of an outer Activity inside onPreExecute(), onPostExecute() and onProgressUpdate() without passing the whole UI structure(s) to the AsyncTask. You are just able to use the activites functions for that.
This is useful since manipulating the UI isn't the main purpose of an AsyncTask. It's doing non-UI background work. And for that, what you usually have to pass is some arguments to do this job (e.g. supplying a URL to download a file).
When you declare your AsyncTask external, you basically can't access your UIs resources inside onPreExecute() (no arguments are passed to this at all), and very hard inside the other two UI functions.
I'd say AsyncTask is just made for beeing used as an inner class to do work and update the UI-thread. See the description:
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.
(from the class documentation)
I had the same problem in may application. I wanted to establish a communitation with a PC using a Socket and I wanted my code to be reusable from several Activities/Fragments.
In the first place I tried not to use an inner class but it is very convenient when you have to update the UI so I found an alternative solution :
I created an outer AsyncTask class wich in charge to communicate with the pc and I created inner classes in each of my activites/fragments with only an override of the onPostExecute() method. this way I can reuse my code AND update the UI.
If you just want to get the result of the task and if responsiveness is not essential for your application, you can use the get() method of the AsyncTask class.
Personally I belive that if you use class only at one point, then it's most readable to also define it there - hence the anon inner class.
It does not matter. From design perspective I'd only pass data that is actually needed. However you need to be aware on one possible pitfall - when activity instance gets deactivated (hidden or orientation changed) and your background thread still runs and tries to show some changes, then you can get various errors or nothing s shown at all.

What exactly does using the Application Context mean?

I'm new to this and I'm sorry if this is a really dumb question. I'm just trying to clarify things. My book says I can retrieve application context for process by using the getApplicationContext() method. I just really don't know where to type this or what to do with any of it. I can go to the hierarchy but what do I do with all the script there. Also where would I write Activity Callbacks, in the main.xml? An exercise wants me to add a logging tag to my project but I'm not sure how to do this. The exact text says:
"Within the onCreate() callback method, add an informational logging message, using the Log.i() method."
and another exercise says to:
"Implement some of the Activity callback methods in addition to onCreate(), such as onStart(). Add a log message to each callback method and then run the application normally".
As these seem like basic questions, can someone please help me.
I am using the Android SDK, and Eclipse. I have made the Hello World application, but I have no idea what to do with Context or Retrieving resources. Please help!
The first rule I would give you: if you don't know why you need it, you probably don't need it. Use your activity object as the Context when you need a context.
The callbacks you talk about are on the Activity class. The Application Fundamentals describes what an Activity is: http://developer.android.com/guide/topics/fundamentals.html#Components
The only time you want to use getApplicationContext() is when you need a Context that exists outside of the lifecycle of an Activity class (or other component). You'll want to find documentation on specific cases where this is desired, there is a lot floating around. For example this one is part of the Android documentation: http://android-developers.blogspot.de/2009/01/avoiding-memory-leaks.html
For the tasks you're working with here, you'll be using the Java code that defines the behavior of the application, not the XML files that define resources and layouts or the AndroidManifest.xml file that declares basic application properties.
If you're working with Hour 3 of the Sam's Teach Yourself... book, then you need to open the src\com.androidbook.droid1\DroidActivity.java file. In general, you would need src\<package-name>\<class-name>.java. When you open that file, you'll see a class (in this case, DroidActivity) that extends Activity and already has the onCreate() callback method. Anything that you want to happen during onCreate() goes inside that method. Other callback methods can be added inside the activity class. To see an example that has all the lifecycle callbacks (but doesn't do anything in them), look here.
A logging tag is just a string. You can declare it, for example, as a private static final String inside the activity class.
If there's confusion about where methods belong, where and how to define variables or constants, how to call methods, how to use classes, and so forth, then it might be best to go through an introductory Java text before starting with Android. There are plenty of free resources available for that.

Categories

Resources