I'm pretty new to AsyncTask on Android, I'm trying to pass an int with
new startTestAsync().execute(grayVal);
to this AsyncTask
public class startTestAsync extends AsyncTask<Integer, Void, Void> {
double[] timeArray = new double[500]; // set array
double lagStartTime;
double lagEndTime;
double lagTimeResult;
int testAmount;
protected void doInBackground(int...grayVal) {
for (testAmount = 0; testAmount < 500; testAmount++) {
lagStartTime = System.nanoTime(); //start lagTimer start
while (grayVal >= 100) {
Log.i("Mat Value", String.valueOf(grayVal));
lagEndTime = System.nanoTime();
}
}
}
Android studio says that "AsyncTask must be abstract", I have no idea how to fix this as I am new to AsyncTasks.
edit: full code http://pastebin.com/vrf8Rb3h
From the documentation:
AsyncTask must be subclassed to be used. The subclass will override at
least one method (doInBackground(Params...)), and most often will
override a second one (onPostExecute(Result).)
That means, you have to override the method onPostExecute(Result) too:
protected void onPostExecute(Long result) {
//Do something
}
you can pass parameters to AsyncTask with two approach.
these are:
1-make parameterized constructor.means
You can override the constructor. Something like:
private class MyAsyncTask extends AsyncTask<Void, Void, Void> {
public MyAsyncTask(int showLoading) {
super();
// do stuff
}
// doInBackground() et al.
}
and call this AsynTask like
MyAsyncTask task = new MyAsyncTask();
task.showLoading = 12;
task.execute();
2-pass values in execute() statement.
public class MyAsyncTask extends AsyncTask<MyClass, Void, Boolean> {
#Override
protected Boolean doInBackground(MyClass... params) {
// Do blah blah with param1 and param2
MyClass myClass = params[0];
String param1 = myClass.getParam1();
String param2 = myClass.getParam2();
return null;
}
}
and call it like
AsyncTask asyncTask = new MyAsyncTask().execute(new MyClass());
enjoy your code:)
You should be doing it like this:
protected Void doInBackground(Integer... grayVal)
{
for (testAmount = 0; testAmount < 500; testAmount++)
{
lagStartTime = System.nanoTime();
while (grayVal[0] >= 100) // you need to loop over grayVal properly if you are sending multiple values(it's just an example), if there is just one value you can write grayVal[0].
{
Log.i("Mat Value", String.valueOf(grayVal.intValue()));
lagEndTime = System.nanoTime();
}
}
return null;
}
you set the parameters of doInBackground to int, it should be an Integer and the return is a Void rather than a void so you should explicitly return null.
Related
I want to know how to access the data and bind it to a component in out of the AsyncTask class body?
I have a class like:
class DownloadData extends AsyncTask<String, Void, String> {....}
and it has a method :
#Override
protected String doInBackground(String... params) {
return ....;//return some data
}
I don't understand doInBackground return data to where?
Because when i want to use my class, i use it like:
DownloadData dd = new DownloadData();
dd.execute(...);
can i use it like this? because i want to fetch returned data out of my main class to bind it to some components
DownloadData dd = new DownloadData();
string temp=dd.doInBackground(...);
After doInBackground() your return will be forwarded to onPostExecute().
To use it in your activity refer this link : How to use Async result in UIThread
I can not catch
#Override
protected String doInBackground(String... params) {
return ....;//return some data
}
result from main UI.
You have to use callbacks. For example, you can use interface to obtain the result.
For example create an interface:
public interface IProgress {
public void onResult(int result);
}
create class:
private class DownloadData extends AsyncTask<String, Void, String> {
private IProgress cb;
DownloadData(IProgress progress) {
this.cb = cb;
}
#Override
protected String doInBackground(String... params) {
for (int i = 0; i < 10; i ++) {
if (cb!=nil)
cb.onResult(i);//calls 10 times
}
....
}
...
}
somewhere in code:
DownloadData dd = new DownloadData( new IProgress() {
public void onResult(int result) {
/// this is your callback
//to update mainUI thread use this:
final res = result;
runOnUiThread(new Runnable() {
#Override
public void run() {
//update UI here
textview.setText("" + res);
}
});
}
});
dd.execute(...);
And, as usual, you can update UI after doInBackground via onPostExecute()
If you just want to return a result from your AsyncTask class so that you can update the UI in your activity according to the result you can do something like this:
In your AsyncTask class declare an interface like this:
private AsyncResponse asyncResponse = null;
public DownloadData(AsyncResponse as) {
this.asyncResponse = as;
}
public interface AsyncResponse {
void onAsyncResponse(String result); // might be any argument length of any type
}
and in onPostExecute() :
asyncResponse.onAsyncResponse(result); // result calculated from doInBackground()
and in the activity class:
DownloadData dd = new DownloadData(new AsyncResponse() {...}); // implement onAsyncResponse here
dd.execute();
I am trying to return a boolean from my method checkInvited(). This method contains a class which extends AsyncTask<Void,Void,String>. This is the full method
public boolean checkInvited(String player_id){
final String g_id = game_id;
final String fr_id = player_id;
class CheckInvited extends AsyncTask<Void, Void, String>{
boolean invited;
ProgressDialog loading;
#Override
protected void onPreExecute(){
super.onPreExecute();
loading = ProgressDialog.show(InviteFriends.this,"Checking Invite Status","Please Wait...",false,false);
}
#Override
protected void onPostExecute(String s){
super.onPostExecute(s);
loading.dismiss();
JSON_STRING = s;
if (s.trim().equals("0")){
invited = false;
} else {
invited = true;
}
}
#Override
protected String doInBackground(Void... params){
HashMap<String, String> hashMap = new HashMap<>();
hashMap.put(Config.KEY_INVITES_GAME_ID, g_id);
hashMap.put(Config.KEY_INVITES_PLAYER_ID, fr_id);
RequestHandler rh = new RequestHandler();
String s = rh.sendPostRequest(Config.URL_CHECK_INVITED, hashMap);
return s;
}
}
CheckInvited ci = new CheckInvited();
ci.execute();
return ci.invited;
}
This method calls a predefined method of sendPostRequest() which contacts the mySql database through php. My problem is getting the checkInvited() method to return true or false. Currently it will only return false when I know at least one of the results should be true.
Thanks in advance for any help.
It only returns false because async task runs in a seperate thread and might take long to execute depending on carious factors. You are returning value even before async task completes.
I would suggest calling a method which requires the true or false from onPostexecute, as onPostExecute runs after doInBackground completes.
I have a list of objects with certain states
private ArrayList<MyObjectMap> MyList;
MyList = new ArrayList<>();
Every object in that list contains a certain value, that can be updated via the internet (say active, inactive). To update each element I use an AsyncTask, so something like this
for(int i=0;i<MyList.size();i++) {
new myAsyncTask(MyList.get(i)).execute();
}
Later, to update the List in my GUI, I use notifyDataSetChanged for the BaseAdapter of my list.
Is this somehow possible? How do I need to change my AsyncTask?
public class myAsyncTask extends AsyncTask<Void, Void, Void> {
private MyObjectMap myObject;
protected void onPreExecute() {
}
public myAsyncTask(MyObjectMap mom) {
myObject = mom;
}
#Override
protected Void doInBackground(Void... voids) {
myObject.updateThisItem();
return null;
}
}
Pass the full arrayList and baseAdapter object to the asyncTask. and update the current element of arrayList and then make notifyDatasetchanged()
public class MyAsyncTask extends AsyncTask<Void, Void, Void>
{
private ArrayList<MyObjectMap> myList;
private BaseAdapter baseAdapter;
private int position;
public MyAsyncTask(ArrayList myList, int position, BaseAdapter baseAdapter) {
this.myList = myList;
this.position = position;
this.baseAdapter = baseAdapter;
}
protected void onPreExecute()
{
}
#Override
protected Void doInBackground(Void... voids)
{
myList.get(position).updateThisItem(); //or
/*
MyObjectMap mop = myList.get(position);
mop.updateThisItem();
myList.remove(position);
myList.add(position, mop);
*/
return null;
}
protected void onPostExecute()
{
baseAdapter.notifyDataSetChanged();
}
}
you can update ui components in asyncTask in both onPreExecute and onPostExcute...
#Prassana has already shown you how to pass objects to AsyncTask by using a constructor, but there is another elegant way to do it, by altering the AsyncTask class type paramers. If I wanted to pass an ArrayList< String> to AsyncTask, and receive an ArrayList< Integer> back, the class layout would look something like this.
// notice the return type and parameter type
public class myAsyncTask extends AsyncTask <ArrayList<String>, Void, ArrayList<Integer> {
...
// Make sure this method receives and returns the correct types.
// the params are specified when you make the call to execute the asynctask and
// are accessed in a usual varargs way (like an array).
#Override
public ArrayList<Integer> doInBackground(ArrayList<String>... params) {
...
// onPostExecute takes the ArrayList returned by doInBackground
#Override
public void onPostExecute(ArrayList<Integer> result) {
// do something with your newly acquired ArrayList<Integer>
Note that this is the main structure, just to give you an idea. I cannot garauntee that this is typo-less code. Good luck!
public class myAsyncTaskextends AsyncTask<Object, Void, Void> {
private MyObjectMap myObject;
protected void onPreExecute() {
}
#Override
protected Void doInBackground(Object... voids) {
myObject = (MyObjectMap)param[0];
myObject.updateThisItem();
return null;
}
}
when we execute asyn task use this code to send object
Asyntask.execute(loginRequestBean);
inside background method you can get object like this
#Override
protected Object doInBackground(Object... params) {
Object responseObject = null;
try {
Object object = params[0];
if (object instanceof LoginRequestBean) {
//login webservice
} else if (object instanceof RegisterBean) {
//registration webservice
}
}
I'm new in Android. It's been a few weeks since I started working in this project. Reading the code already made I see a lot of private async tasks doing basically the same (call an API) So I wonder if there is a better solution, my idea would be create a public async task called ApiCaller which will return a JSONObject and the responsible for parsing the JSON would be the class calling the ApiCaller:
public class ApiCaller extends AsyncTask<String, String, JSONObject> {
private static final String TAG = "ApiCall";
private final String apiVersion = "v1";
private final String baseURL = "http://my.api.com/";
private String URL = null;
/**
* Generates the URL to call the API.
*
* #param params List with the params to call the API.
*/
public ApiCaller(ArrayList<NameValuePair> params){
String apiURL = this.baseURL + this.apiVersion + "/?";
String paramsList = URLEncodedUtils.format(params, "utf-8");
this.URL = apiURL + paramsList;
}
#Override
protected JSONObject doInBackground(String ... params) {
Log.i(TAG, "API:");
Log.i(TAG, this.URL);
JSONManager jParser = new JSONManager();
JSONObject jsonObject = jParser.getJSONFromUrl(this.URL);
return jsonObject;
}
Is there a way to return that JSONObject outside of the class so I can do something like:
JSONObject js = apiCaller.execute();
Or any other solution to avoid creating new asynctasks every time I need to call the API? With my current code I can't get it but I don't know what is missing? maybe returning it in onPostExecute?
Some time ago I've asked a similar question
One AsyncTask for multiple Activities
and the solution I found was answered in another question:
Common class for AsyncTask in Android?
Basically, what you need is an interface.
I've going to explain the basics, although you should check the original answer by #SirDarius.
You could create an interface like this:
interface AsyncTaskCompleteListener<T> {
public void onTaskComplete(T result);
}
And implements that interface in all classes you need to use the AsynTask, then, in your generic Asynstask you need to have a callback AsyncTaskCompleteListener and call it from your onPostExecute
class B implements AsyncTaskCompleteListener<JSONObject> {
public void onTaskComplete(JSONObject result) {
// do whatever you need
}
public void launchTask(String url) {
ApiCaller a = new ApiCaller(context, ArrayList<NameValuePair> params, this);
ApiCaller.execute(url);
}
}
class ApiCaller extends AsyncTask<String, Void, String> {
private AsyncTaskCompleteListener<String> callback;
public ApiCaller(Context context, ArrayList<NameValuePair> params, AsyncTaskCompleteListener<String> cb) {
this.context = context;
this.callback = cb;
}
protected void onPostExecute(String result) {
finalResult = result;
progressDialog.dismiss();
System.out.println("on Post execute called");
callback.onTaskComplete(result);
}
}
because the asynchronous AsyncTask you can not call a method and obtain the return value;
you could use a AsyncTask on your inline code and get on postExecute your JSON object:
new AsyncTask<String, String, JSONObject>(){
#Override
protected Void doInBackground(String... params) {
//...
}
#Override
protected void onPostExecute(JSONObject result) {
// ...
}
}.execute(...);
You should implement a listener that you will pass to the async task. When the asynctask finishes, it will call the listener's method:
First, make a listener in a new java file:
public interface onTaskDoneListener{
void onTaskDone(JSONObject result);
}
Pass it to your AsyncTask:
private onTaskDoneListner donelistner;
public ApiCaller(ArrayList<NameValuePair> params,onTaskDoneListener donelistener){
String apiURL = this.baseURL + this.apiVersion + "/?";
String paramsList = URLEncodedUtils.format(params, "utf-8");
this.URL = apiURL + paramsList;
this.donelistener = donelistener;
}
Then, inside the onPostExecute method of your AsyncTask
this.donelistener.onTaskDone(result)
Usage:
new ApiCaller(params,new onTaskDoneListener() {
#Override
public void onTaskDone(JSONObject result) {
//This will be called when the asynctask finishes
//Do something with the result
});
Step 1 : Define an Interface.
public interface WebServiceListener {
public void onLoginActionComplete (ArrayList<String> arrayList);
}
Step 2: Implement the WebServiceListener in your activity class.
public class LoginActivity extends Activity implements WebServiceListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login);
/* Calling the AsyncTask here,you could call in Login Button Click... */
WebServiceClient httpclient = new WebServiceClient(this);
httpclient.execute(ssoURLStr);
}
#Override
public void onLoginActionComplete (ArrayList<String> arrayList) {
// TODO Auto-generated method stub
/* Read the response */
String Response = arrayList.get(0);
}
}
Step 3 : Your AsynTask class code here.
public class WebServiceClient extends
AsyncTask<String, Integer, ArrayList<String>> {
WebServiceListener listener = null;
/* Constructor added WebServiceListener here */
public WebServiceClient ( WebServiceListener listener)
{
this.listener = listener;
}
#Override
protected ArrayList<String> doInBackground(String... params) {
// TODO Auto-generated method stub
ArrayList<String> arrayList = null;
" write your http code here and get the response and update the
arrayList <String> here"
return arrayList;
}
#Override
protected void onPostExecute(ArrayList<String> arrayList) {
// Returns the contents of the HTML page
listener.onLoginActionComplete (arrayList);
}
}
I have also asked this question. Maybe this link will help
i have qualification what is best why to getting data from data base in android.
my code
class MyClass{
List<String> listdata;
public void getData(){
new DownloadTask (){
protected void onPostExecute(List<String> result) {
listdata = result;
// listdata contain 10 records
}
}.execute();
// here list data is null out side asynctask
listdata is null
}
private class DownloadTask extends AsyncTask<Void, Void, List<String>> {
protected List<Stirng> doInBackground() {
return data.getAllRecords();
}
}
}
if anything wrong me correct me , Thanks
listdata is assigned a value in the onPostExecute() which is called at a later point after the doInBackground() has finished.
doInBackground(Params...) This step is used to perform background
computation that can take a long time.
onPostExecute(Result) invoked on the UI thread after the background
computation finishes. The result of the background computation is
passed to this step as a parameter.
You execute the task and then try to access the value of listdata in the next line. It will be null as the task has not completed as yet, the onPostExecute() has not been called yet.
Its not final. You are not using the enclosed value.
class MyClass{
final List<String> listData;
public myClass(){
listData = new ArrayList<String>();
}
public void getData(){
new DownloadTask (){
protected void onPostExecute(List<String> result) {
listData.addAll(result);
listDataRetrieved();
};
}.execute();
private final void listDataRetrieved(){
assertTrue(listData != null && containsCorrectElements());
}
private class DownloadTask extends AsyncTask<Void, Void, List<String>> {
protected List<String> doInBackground() {
return data.getAllRecords();
}
}
}