call a method in an activity from a "normal" class - android

I have one main activity that handles all the UI stuff. In the activity i have a ListView which is in a SlidingDrawer, above that are 4 TextViews.
I want to change the text of the 4 TextViews once i click on an item from the ListView.
I get the text from an online database, so i put the code for that in an extra class.
I created a reference to the workerclass:
final OneTopic ot = new OneTopic();
In my onClickListener I call the method from the workerclass
ot.postData(position);
At the beginning of the workerclass i have a reference to the main class
Main main = new Main();
when the worker class is finished, it calls the method that updates the UI in the Activity.
main.displayText(body, title, date, poster);
The method its calling looks like this:
public void displayText(String body, String title, String date, String poster) {
tx_body.setText(Html.fromHtml(body));
tx_title.setText(title);
tx_date.setText(date);
tx_poster.setText(poster);
}
If I do this my app force closes once it tries to set the text.
What am I doing wrong?

At the beginning of the workerclass i have a reference to the main
class
Main main = new Main();
That's actually creating a new instance of your Main class, not getting a reference to the current one. If you want a reference to your activity from your worker thread, then you need to pass in your activity as a parameter.
ot.postData(Main.this, position);

Without seeing your entire code, I see two possibilities:
Your WorkerThread is not running in the UI Thread and you can only update UI objects from within the UI Thread. Check out the Worker Threads topic in the Android dev guide. Basically the code for displayText() is what needs to go in the Runnable in the example I just provided you.
I am slightly troubled at this statement:
At the beginning of the workerclass i have a reference to the main class Main main = new Main();
If Main is your activity, then you should not be constructing a new one. You need a reference to the Activity instance that started the worker thread.
Hope this helps. I see you're new to StackOverflow. If this answers your question, please mark it as accepted. Good luck!

Related

Android: Updating UI from thread in separate class

I am attempting to update a few UI elements in my app, after a separate class has been updated. The separate class is neither an activity nor a fragment. Could anyone point me in the right direction? Would a handler work well here, if so could you point me toward a acceptable example of handlers?
you can use this in a separe class.
public void setView(Activity activity, View view) {
activity.runOnUiThread(new Runnable() {
public void run()
{
/update your view here
}
});
}
You can get the view from your activity variable, instead of pass a view, if you prefere.
You cannot update any UI elements from a different thread than the main thread. If you are using the main thread, you can pass the View to the method in the other class and make some changes with that.
You need to link the two classes together by perhaps implementing a callback mechanism that will be processed using a handler into your main application thread, assuming that your external class can register a callback with the Activity class.
Or more simply you could use context by allowing a reference to be passed from the Activity to your other class, but you want to make sure you don't leak context.

Android with ASYNC Task

I'm wondering where I should place my AsyncTask in my android project. As of right now I'm implementing an AsyncTask as a private class of my activity its running under. What I am going to do is in each activity that has a network call I will implement its own private class of AsyncTask. I have a few questions though
In The preexecute method it says I can interact with the activity and place a spinner or progress bar. I do this by using My_Activity_Class_Name.this. So my question is does that line of code reference the activity the AsyncTask is called from? If so I believe that will be a static method. How do i actually pass in the instance of the class so I can interact with non static functions?
I want to place all my Async code into one class for its respective needs. My quesiotn though is if i need to return a type back to the class that calls the Async method how can I return a value? Also is this the best practice?
You should make your inner private AsyncTask class - static. This is because otherwise it will have implicit reference to your Activity - this means that if your Activity will be recreated - ie. due to config change - then your AsyncTask will still hold your activity reference causing reference leak. This means you should pass reference to your activity to AsyncTask in ie. constructor of AsyncTask, and keep it in WeakReference (WeakReference/AsyncTask pattern in android).
So my question is does that line of code reference the activity the ASYNC Task is called from?
yes, but only if your AsyncTask class is non static
If so I beleve that will be a static method. How do i actually pass in the instance of the class so i can interact with non static functions?
its not a static method, with My_Activity_Class_Name.this you can access non static methods of your Activity class.
My quesiotn though is if i need to return a type back to the class that calls the Async method how can I return a value? Also is this the best practice?
You can call a method on your Activity class, there is nothing wrong with that. Remember that you cannot access UI widgets from non UI thread. So update your Activity widgets from onPostExecute which is called on UI thread.

Event listener in a broadcast receiver?

So, this is probably a very basic design question, but Im just not sure how to go about it.
Normally, when I use event listeners, I define it in whatever class, then I override the necessary methods in my Activity and instantiate the class and the listener as needed.
However, in this case, I have my MainActivity class (that also implements the listener), a class (called testClass) that implements the listener, and a broadcast receiver class. The broadcast receiver class instantiates the calls the testClass. Now, what I am trying to do is to update a TextView in MainActivity when a given function is called in the testClass.
Not sure how to go about this.
Hope this wobbly issue description makes sense.
This is a problem I've tackled in the past when using a background Service to update data that is displayed on screen. The general pattern I use is to add a member variable to your processing class (in this case, I think it's your TestClass) that is a Map (named something like mCallbackMap) with android.os.Handler as the key and your listener object as the value (normally this will be an interface that you define). The Handler, which is created in the Activity and thus associated with the main thread, is needed because you can't change the UI of an Activity from outside the main Thread; you'll use the Handler to post a runnable to the main thread instead of manipulating it directly.
When your activity gets going, probably in onCreate, onStart, or onResume, you'll register it as a callback with your TestClass by using the mCallbackMap's put() method. Simply instantiate a Handler, which you'll also store as a member variable of your activity, and use it as the key and your Activity as the value. You'll need to remove the callback in onPause or onStop so you don't leak the activity after it's out of view.
Then, once TestClass finishes handling whatever the broadcast gives it, you'll iterate through your mCallbackMap (maybe you have more than one callback, maybe you don't) and call Handler.post(Runnable). In the Runnable's run() method, you call the callback's methods as appropriate.

Pass Variables from AsyncTask back to calling to Activity

I am new to Android Development and have a question (will probably show my newbie status). I am calling an asynchtask from a custom activity. Once the asynch task is completed onPostExecute I would like to call back into my activity and set a pojo (Map()). I know that onPostExecute seems to run on the UI thread but I am not sure how to get visibility into the calling Activity.
The goal is to be able to have some variables set in my activity and ideally the webservice call will already be completed.
Thanks,
Craig
If the AsyncTask is a subclass of the activity, it has access to all public, protected, and private variables of the superclass. If its not, you need to write a public function in the Activity class to set the variables, and call it from the AsyncTask. That will probably require you to pass the activity to the AsyncTask via the constructor and save it in a member variable of the task.

Android AsynkTask problem with HttpUtilities class

I want to tell you about the structure of my classes.
I have an HttpUtilities class, from which I am doing requests(send and get JSON objects) to server. It's a public class with private constructor and static methods.
I have also user class which manipulates data(set string to JSON, and JSON to ...).
Within my activity I have declared the instance of user class.
There are some methods(SignIn, SignOut, InserToListView) there which call corresponding methods of httpUtilities.
Now, I want, that for each event of user, using AsynkTask do request to server and change ui.
I want to call method(for example InserToListview) of user class within new Thread using AsynkTask.
It would be easier if you tried your hand at this first and then asked questions later, but here is some general advice to get you started:
Subclass AsyncTask.
Implement doInBackground, calling your insert method.
(Wherever you are calling your insert method now) instantiate your subclass of AsyncTask.
Call the execute method on your new custom AsyncTask object.
Store your AsyncTask in an instance variable so you can cancel it later on.

Categories

Resources