Calling functions defined in a class using AsyncTask android - android

My code goes as below :-
public class Activity2 extends ListActivity {
protected void onCreate(Bundle savedInstanceState)
{
.
.
readDatafromfile();
}
public void readDatafromfile(){
..
}
Now I want to do this reading asynchronously. I have created yet another class for this but I am not able to call the method ( readDatafromfile() ).
Please help.

You have three options to do that:
Define readDatafromfile() as static in your Activity class.
public class Activity2 extends ListActivity
{ public void readDatafromfile(){} }
Define readDatafromfile() in your AsyncTask and pass your Activity as context.
public class MyAsync extends AsyncTask < Void , Void , Void >
{
Context ctx;
public MyAsync ( Context ctx ){ this.ctx = ctx; }
public void readDatafromfile(){}
}
Create and interface IOOperation that contains readDatafromfile() , let your activity implement that, and pass it to your AsyncTask.
interface
public interface IOOperation
{ public void readDatafromfile(); }
activity
public class Activity2 extends ListActivity implements IOOperation
{
#override
public void readDatafromfile(){} }
asynctask
public class MyAsync extends AsyncTask < Void , Void , Void >
{
IOOperation reader;
public MyAsync ( IOOperation reader){ this.reader= reader; }
protected Void doInBackground(Void... args)
{ reader.readDatafromfile(); }
}

Related

how to call class AsyncTask to another class?

I tried to call the "AsyncTask" class from another class called "MainActivity" but "AsyncTask" Class is inside the class called "SiteAdapter". I tried to pass a reference but it not working. How could do that?
Main Activity:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i("StackSites", "OnCreate()");
setContentView(R.layout.activity_main);
//Call the class AsyncTask
new GetAddressTask(this).execute(); // <----ERROR - GetAddressTask cannot be resolved to a type
}
}
AsyncTask inside SitesAdapter class:
public class SitesAdapter extends ArrayAdapter<StackSite> {
...//PROCESS
public class GetAddressTask extends AsyncTask<String, Void, String> {
Context mContext;
public GetAddressTask(Context context) {
super();
mContext = context;
}
//Pass a reference to MainActivity
private MainActivity mainActivity; // <--- WARNING - The value of the field SitesAdapter.GetAddressTask.mainActivity is not used
public GetAddressTask(MainActivity mainActivity)
{
this.mainActivity = mainActivity;
}
#Override
protected String doInBackground(String... arg0) {
...
}
#Override
protected void onPostExecute(String result) {
...
}
}
}
First of all, MainActivity is not a class that you can not define an object from. It extends Activity.
Change your AsyncTask class with it;
public static class GetAddressTask extends AsyncTask<String, Void, String> {
Context mContext;
public GetAddressTask(Context context) {
super();
mContext = context;
}
#Override
protected String doInBackground(String... values) {
// If you want to use 'values' string in here
String values = values[0];
}
#Override
protected void onPostExecute(String result) {
...
}
}
Then call this with it;
String values = ""; //You can pass any string value to GetAddressTask with that parameter
//Call the class AsyncTask
new SitesAdapter.GetAddressTask(this).execute(values);
make GetAddressTask static:
public static class GetAddressTask
Try this, this is working for me.
Just create a method in your SitesAdapter class and call it from your MainActivity like this :
new SitesAdapter().start(MainActivity.this);
now in your SitesAdapter class do this :
private Context mContext;
public void start(){
mContext = context;
new GetAddressTask().execute();
}
May this help you
You could make it static then call it with
SitesAdapter.GetAddressTask myClass = new SitesAdapter.GetAddressTask();
myClass.execute();
But, if you are going to be needing this in multiple activities, then it is probably worth it to take it out of that class and put it in its own file.
If you will need to update your UI from the task, you can see this answer on using an interface with a callback to your calling Activity.

how to call method in activity form non activity class

I have an Activity and non Activity class. How to call a method in Activity class from non Activity class
public class MainActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main2);
DataClass dc = new DataClass();
dc.show();
}
public void call(ArrayList<String> arr) {
// Some code...
}
}
public class DataClass {
public void show(ArrayList<String> array) {
// Here I want to send this ArrayList values into the call
// method in activity class.
MainActivity act = new MainActivity();
act.call(array);
}
}
Just create a callback interface inside the DateClass.
public DateClass {
public interface IDateCallback {
void call(ArrayList<String> arr);
}
private IDateCallback callerActivity;
public DateClass(Activity activity) {
callerActivity = (IDateCallback)activity;
}
...
}
public void show(ArrayList<String> array) {
callerActivity.Call(array);
...
}
//And implements it inside your activity.
public class MainActivity extends Activity
implements IDateCallback {
public void call(ArrayList<String> arr) {
}
}
Well there are several things you could do. I think the easiest for you would be to send the Context into DataClass like so:
DataClass dc =new DataClass();
dc.show(this);
And in your DataClass save the context into a global var Context context. Then use it like so:
((MainActivity)context).call(array);
((MainActivity)getContext).array();
Just make a singleton like:
TeacherDashboardSingleton:
public class TeacherDashboardSingleton {
public Teacher_Dashboard aa;
private static final TeacherDashboardSingleton ourInstance = new TeacherDashboardSingleton();
public static TeacherDashboardSingleton getInstance() {
return ourInstance;
}
}
myActivity class:
onCreate(....){
....
TeacherDashboardSingleton.getInstance().aa = this;
....
}
this will create an object of same instance as in activity
now you can use it from anywhere

How to use one AsyncTask Class to apply different Activity in Android

I have a AsyncTask class that connect to web service to get something and then print to the screen.
Here is my code:
public class GetCreditAsyncTask extends AsyncTask<Object, Boolean, String>{
private MainActivity callerActivity;
private String credit;
public GetCreditAsyncTask(Context context){
callerActivity = (MainActivity )context;
}
#Override
protected String doInBackground(Object... params) {
.....//do something and get the credit
}
#Override
protected void onPostExecute(String response) {
callerActivity.txtView.setText(credit);
}
}
It works perfect but now, I have one more Activity ProfileActivity
which also want to use GetCreditAsyncTask to get the credit and print it to the txtView,
but at the begining of GetCreditAsyncTask, I cast the callerActivity to MainActivity.
The question is how to just use one AsyncTask class so that I can call it and get the credit.
You can define an interface that both activities implement. Instead of casting to MainActivity, you must cast to this interface.
public interface ActivityListener {
public void setText(String text);
}
public class MainActivity extends Activity implements ActivityListener {
...
public void setText(String text) {
TextView tv = findViewById(R.id.main_text);
tv.setText(text);
}
}
public class SecondActivity extends Activity implements ActivityListener {
...
public void setText(String text) {
TextView tv = findViewById(R.id.secondary_text);
tv.setText(text);
}
}
public class GetCreditAsyncTask extends AsyncTask<Object, Boolean, String>{
private ActivityListener callerActivity;
private String credit;
public GetCreditAsyncTask(Context context){
callerActivity = (ActivityListener) context;
}
#Override
protected String doInBackground(Object... params) {
.....//do something and get the credit
}
#Override
protected void onPostExecute(String response) {
callerActivity.setText(credit);
}
}

Call a public method in the Activity class from another class?

MAIN ACTIVITY
public class MyActivity() extends Activity
{
onCreate()
{
MyClass myobj=new MyClass();
}
public void Mymethod()
{}
}
//HELPER CLASS IN A SEPARATE FILE
public class MyClass()
{
MyClass(Context context)
{
}
}
I tried to call Mymethod() from an instance of MyClass.
I would really appreciate any help. Thanks.
Why not just pass the activity to the constructor like
public class MyActivity extends Activity {
onCreate(){
MyClass myobj=new MyClass(MyActivity.this);
}
public void myMethod(){
}
}
//HELPER CLASS IN A SEPARATE FILE
public class MyClass{
public MyClass(MyActivity act) {
act.myMethod();
}
}
Make that method as static so you can call without creating the class object
public static void Mymethod()
{}
and call like this way
MainActivity.Mymethod();
This is probably the best way to do it. This is how I'm doing it. It's called a Singleton Design Pattern:
public class MyActivity extends Activity {
private static MainActivity instance;
public static MainActivity getInstance() {
if(instance==null){
setInstance(this);
}
return instance;
}
public static void setInstance(MainActivity instance) {
MainActivity.instance = instance;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setInstance(this);
}
}
If I'm understanding you correctly I believe you can solve your problems using an interface as a callback.
////ACTIVITY/////////////////////////////////
public class MyActivity() extends Activity {
onCreate()
{
MyClass myObj=new MyClass();
//Set the listener on the object. Created as anonymous
myObj.setListener(new MyClass.Listener() {
myMethod();
});
}
}
public void myMethod(){
}
//////Custom Class//////////////////
public class MyClass {
Listener mListener;
public interface Listener {
public void onInterestingEvent();
}
public void setListener(Listener listener) {
mListener = listener;
}
public void someUsefulThingTheClassDoes() {
//Do your code here and when you're ready to call the activity's method do this
mListener.onInterestingEvent();
}
}
I had an inner class that I wanted to pull out into a more general library "Helper" class. I had the same issue you do. I got around it by making the helper class abstract, with a single abstract method. Then in my project package I extended the helper class with a constructor call in the specific class.
public class MyActivity extends Activity {
onCreate() {
MyHelperClass = new MyHelperClass(this, "foobar");
}
public void myMethod() {
// Code...
}
}
// In a different file
public class MyHelperClass extends HelperClass {
private MyActivity mInstance;
public MyHelperClass(MyActivity act, String data) {
super();
this.mInstance = act;
this.mActivity = act; // Useful for calling generic Activity methods in the HelperClass
this.mData = data;
}
protected void callMyActivityMethod() {
mInstance.myMethod();
}
}
// In a different file
public abstract class HelperClass {
protected Activity mActivity;
protected String mData;
public HelperClass() {
// Subclass will set variables
}
protected abstract void callMyActivityMethod();
// More code for all the other stuff the class does
}
In this way, I have a helper class that contains the vast majority of the "work", and all I have to do is make a subclass with the constructor and one method in order to get access to the calling activity's method of interest.
You have to pass instance of MainActivity into another class, then you can call everything public (in MainActivity) from everywhere.
MainActivity.java
public class MainActivity extends AppCompatActivity {
// Instance of AnotherClass for future use
private AnotherClass anotherClass;
#Override
protected void onCreate(Bundle savedInstanceState) {
// Create new instance of AnotherClass and
// pass instance of MainActivity by "this"
anotherClass = new AnotherClass(this);
}
// Method you want to call from another class
public void myMethod(){
...
}
}
AnotherClass.java
public class AnotherClass {
// Main class instance
private MainActivity mainActivity;
// Constructor
public AnotherClass(MainActivity activity) {
// Save instance of main class for future use
mainActivity = activity;
// Call method in MainActivity
mainActivity.myMethod();
}
}
In MainActivity.class file
You have to pass MainActivity context from MainActivity Class. Then in MyClass you have to Get MainActivity context. Remember Context and MyActivity are two different reference.
public class MyActivity extends Activity
{
onCreate(){
MyClass myobj=new MyClass(MyActivity context);
}
public void Mymethod(){}
}
//HELPER CLASS IN A SEPARATE FILE
public class MyClass()
{
MyActivity context;
MyClass(MyActivity context)
{
this.context = context;
this.context.Mymethod();
//Or you can directly use activity context
context.Mymethod();
}
}
I decided to write the HelperClass MyClass as an inner class of MyActivity class. This allows it full access to parent class but the bad thing is now MyClass is restricted to MyActivity class only.
public class MyActivity() extends Activity
{
onCreate()
{
MyClass myobj=new MyClass();
}
public void myMethod()
{
}
}
//INNER CLASS
public class MyClass
{
public MyClass()
{
}
//I can directly access the MyMethod
myMethod();
}

How to call parent activity function from ASyncTask?

setAccountAuthenticatorResult can be called from the Activity, which extends AccountAuthenticatorActivity. My activity extends that, but launches ASyncTask and hence this setAccountAuthenticatorResult should be called from ASyncTask (or, the result of ASyncTask should be passed back to the main thread).
How to do it?
What is wrong in the code below?
AsyncTask<Uri, Void, Bundle> task = new RetrieveAccessTokenTask(this, consumer, provider, prefs).execute(uri);
public class RetrieveAccessTokenTask extends AsyncTask<Uri, Void, Bundle> {
private Context context;
public RetrieveAccessTokenTask(Context context, OAuthConsumer consumer,
OAuthProvider provider, SharedPreferences prefs) {
this.context = context;
}
#Override
protected void onPostExecute(Bundle result) {
context.setAccountAuthenticatorResult(); // doesn't work
}
When you create the AsyncTask, you can add a new constructor to it, and pass in a reference to the Activity:
AsyncTask myTask = new MyTask(this);
And then from the onPostExecute() method in the AsyncTask you can call the method on the Activity.
public class MyTask extends AsyncTask<String, String, String>
{
public MyActivity activity;
public MyTask(MyActivity a)
{
this.activity = a;
}
// ......
protected void onPostExecute(String result)
{
activity.myMethod();
}
}
Use Interface
Follow these steps:
1) Create an interface
public interface AsyncTaskListener{
public void updateResult(String result);
}
2) Use the listener in your AsyncTask
DownloadSongTask extends AsyncTask<String,Integer,String>{
private AsyncTaskListener listener;
public DownloadSongTask(Context context)
{
listener= (AsyncTaskListener)context; // Typecast
}
#Override
public void doInbackGround(String... params)
{
// Download code
int downloadPerc = // calculate that
publish(downloadPerc);
}
#Override
public void onPostExecute(String result)
{
listener.updateResult(String result); // Use it
}
}
3) Implement the interface in your Activity and Override the interface method
public class YourActivity extends AppcompatActivity implements AsyncTaskListener{
// Activity code //
new DownloadSongTask(this).execute("Paradise.mp3"); // this is how you start Task
public void yourMethod(String arg)
{
// Your method related Stuff
}
#Override
public void updateResult(String result){
yourMethod(result);
}
}
Advantege of using interface?
This seems a lengthy approach at first but if you use this approach
You can make a loosely coupled AsyncTask. Which means you can use same AsyncTask with any Activity in Future without even changing code in your AsyncTask.
Relevant Links:
For better understanding you can read this ANSWER

Categories

Resources