Android AsyncTask pass variable value - android

How do I pass value on doInBackground so It can use it. When I type the String directly inside doInBackgroud it works. But I have three type "Professional", "General", "Special" I don't want to create 3 asyncTask. In my research i found that I need to create contructor but im don't get It.
String type = "professional";
new loadQuestioners().execute(type);
public class loadQuestioners extends AsyncTask <String, Integer, JSONArray> {
#Override
protected JSONArray doInBackground(String... arg0) {
//is the arg0 is the type i passed?
return null;
}
}

Just modify the code as follows,
public class loadQuestioners extends AsyncTask <String, Integer, JSONArray> {
#Override
protected JSONArray doInBackground(String... arg0) {
//is the arg0 is the type i passed?
String yourType=arg0[0];
return null;
}
"yourType" contains the type you passed while creating asyncTask

I can see two ways of going about this:
1st:
new loadQuestioners().execute("professional");
public class loadQuestioners extends AsyncTask <String, Integer, JSONArray>
{
#Override
protected JSONArray doInBackground(String... arg)
{
String word = arg[0];
return null;
}
}
And 2nd: create a constructor and pass the argument:
new loadQuestioners("professional").execute();
public class loadQuestioners extends AsyncTask <String, Integer, JSONArray>
{
private String word;
public loadQuestioners(String word)
{
this.word = word;
}
#Override
protected JSONArray doInBackground(String... arg0)
{
//use word
return null;
}
}

String... args means that it can take as paramrters:
a single String object OR
an array of Strings
So in your case pass an array of Strings to your async task's execute method and doInBackground will get them just fine. Inside doInBackground use the arg0 parameter as a String array and you should be good.

Related

How can I create AsyncTask of my getTotalIncomeAmount() which is an Integer type function in my IncomeDao class

I want to get total income amount from my Income table which have Amount table
#ColumnInfo(name = "Amount")
private int amount;
And in my IncomeDao I've
#Query("SELECT SUM(amount) from income_table")
Integer getTotalIncomeAmount();
And in my IncomeRepository I've
public Integer getTotalIncomeAmount()
{
return incomeDao.getTotalIncomeAmount();
}
In my IncomeViewModel
public Integer getTotalIncomeAmount()
{
return incomeRepository.getTotalIncomeAmount();
}
And I call this in my Main thread like this
totalIncome = incomeViewModel.getTotalIncomeAmount();
But it gives me the error that 'Cannot access database on the main thread since it may potentially lock the UI for a long period of time.'
I know this error can be remove by creating LiveData<Integer> getTotalIncomeAmount().
But I don't want to do this by LiveData because I've to observe it which is not good in my case.
I want someone to show me how to create AsyncTask of this method in my IncomeRepositoryclass because I know this is the only way to get rid of this error.
I'm fairly new in programming.
As I created other AsyncTask like this in my IncomeRepository
private static class UpdateIncomeAsyncTask extends AsyncTask<Income, Void, Void>
{
private IncomeDao incomeDao;
private UpdateIncomeAsyncTask(IncomeDao incomeDao)
{
this.incomeDao = incomeDao;
}
#Override
protected Void doInBackground(Income... incomes)
{
incomeDao.update(incomes[0]);
return null;
}
}
I just need someone to complete private static class TotalIncomeAmountAsyncTask extends AsyncTask<Void, Void, Void>
for me. I tried very hard but I could succeed.
Thanks in advance
Try below code,
You will get amount in doInBackgroud method from database, after geting value you will get call in onPostExecute method. If you have global variable then you can directly set value in doInBackgroud method.
private void getTotalIncomeAmount() {
class TotalIncomeAmountAsyncTask extends AsyncTask<Void, Void, Integer> {
#Override
protected Integer doInBackground(Void... voids) {
Integer value = DatabaseClient.getInstance(getApplicationContext()).getAppDatabase()
.taskDao()
.getTotalIncomeAmount();
return value;
}
#Override
protected void onPostExecute(Integer value) {
super.onPostExecute(value);
//
}
}
TotalIncomeAmountAsyncTask totalIncome = new TotalIncomeAmountAsyncTask();
totalIncome.execute();
}

How to pass a value to AsyncTask?

What is the proper way in the following code (it's a bit complicated structure to me) to get url from the method gotUrl() to the doInBackground() method of AsyncTask in order to use it in onPostExecute(), after the doInBackground() method has completed its task?
public class PlayerActivity extends CustomActivity implements
ProblemListener{
public class PlayChannel extends
AsyncTask<CustomChangeChannel, String, String> {
#Override
protected String doInBackground(CustomChangeChannel... params) {
initOctoshapeSystem();
return url;
}
#Override
protected void onPostExecute(String url){
}
}
public void initOctoshapeSystem() {
os = OctoStatic.create(this, this, null);
os.setOctoshapeSystemListener(new OctoshapeSystemListener() {
#Override
public void onConnect() {
mStreamPlayer = setupStream(OCTOLINK);
mStreamPlayer.requestPlay();
}
});
}
public StreamPlayer setupStream(final String stream) {
StreamPlayer sp = os.createStreamPlayer(stream);
sp.setStatusChangedListener(new StatusChangedListener() {
#Override
public void statusChanged(byte oldStatus,
final byte newStatus) {
runOnUiThread(new Runnable() {
#Override
public void run() {
//todo
}
});
}
});
sp.setListener(new StreamPlayerListener() {
#Override
public void gotUrl(String url) {
//String to be passed
}
});
return sp;
}
}
AsyncTask<Param1, Param2, Param3>
Param 1 is the param that you pass into your doInBackground method.
Param 2 is what you want to get while the AsyncTask working.
Param 3 is what you want to get as result.
You can declare all them as Void.
AsyncTask<Void, Void, Void>
In your case you want to pass String URL to your doInBackground, so:
AsyncTask<String, Void, Void>
Pass your URL String when you call the execute.
mAsyncTask.execute("your url");
Then get it in the doInBackground:
protected Void doInBackground(String... params) {
String yourURL = params[0];
return null;
}
change this
public class PlayChannel extends
AsyncTask<CustomChangeChannel, String, String>
to this
public class PlayChannel extends
AsyncTask<String, String, String>
and then use
PlayChannel channel = new PlayChannel(url);

get server data to android and automatically display as the server data changes

I am currently working on project. It involves reading data from cloud server continuously. I am using ubidots server. Currently i have created class that extends to asynctask class like this
public class ApiUbidots extends AsyncTask<Integer, Void, Void> {
private final String API_KEY = "1XXXXXXXXX";
private static final String tempID = "56XXXXXXXX";
#Override
protected Void doInBackground(Integer... params) {
final ApiClient apiClient = new ApiClient(API_KEY);
Variable tempVariable = apiClient.getVariable(tempID);
Value[] tempValues = tempVariable.getValues();
Double vlStr = tempValues[0].getValue();
String tempValue = String.valueOf(vlStr);
Log.i(TAG, "TEMPERATURE VALUE IS ====" + tempValue);
tempTextView.setText(tempValue);
return null;
}
}
now i am trying to set the values i got from server to display on textview but i cannot set in this class.
I need to find a way where the textview have to be changed whenever the data variable changes
Can anyone please help me how to proceed to get it working.
Thank you!
If you have this class defined as a subclass, all you need to do is update your TextView in the onPostExecute() method of your AsyncTask. If this task is a class in a separate file, you would define a callback to send data back to the calling Activity, then update your TextView with the data you receive in the callback. Here's some example code:
Your AsyncTask would look something like this. Notice it defines a public interface that acts as a callback for the results of the task.
import android.os.AsyncTask;
public class TestTask extends AsyncTask<String, Void, String> {
TestTaskCallback listener;
public TestTask(TestTaskCallback listener) {
this.listener = listener;
}
protected String doInBackground(String... args) {
String input = args[0];
String output = "simulated return value";
return output;
}
protected void onPostExecute(String result) {
listener.onResultReceived(result);
}
public interface TestTaskCallback {
void onResultReceived(String result);
}
}
Then your calling Activity would implement the callback, fire the Task, then wait for the result, like this:
public class TestActivity extends AppCompatActivity implements TestTask.TestTaskCallback {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.your_layout);
new TestTask(this).execute("Some input");
}
public void onResultReceived(String result) {
Log.d("TEST TASK RESULT", result);
}
}
Once the result comes in, you can use it in your Activity to update your TextView. And as I mentioned above, this is all way easier if you just subclass the Task right in the Activity itself. That way, you'll just have access to your TextViews right from the Task. No need to mess with callbacks at that point.

Pass multiple values in an asynctask and receive corresponding results

In my Android app I am trying to pass in an asynctask during the splash screen multiple values and as a result it will return as many results as the values.
myasynctask task=new myasynctask()
task.execute("value1","value2",etc...)
and return for using in other activities result1, result2, etc.
How to do this?
You could encapsulate them in an DataTransferObject.
public class AsyncTaskDTO{
// implemnt your values
private int foo;
private boolean bar;
// getter and setters.
}
You could also pass a Map, an array or a List.
as ex:
AsyncTaskDto dto = new AsyncTaskDto();
dto.setFoo(2);
task.execute(dto);
List<String> values = new LinkedList<String>();
values.add("value1");
task.execute(values);
When you execute the task as in your code, you will get the values in params[0], parmas[1] etc., to return the same amount of results to onPostExecute I'd suggest to use an array or a list.
private class DownloadFilesTask extends AsyncTask<URL, Integer, ArrayList<String>> {
protected Long doInBackground(URL... urls) {
ArrayList<String> result = new ArrayList<String>();
for (int i = 0; i < params.length; i++) {
value = params[i];
//do stuff
result.add(whatever);
}
return result;
}
protected void onPostExecute(ArrayList<String> result) {
//do stuff...
}
}
from https://developer.android.com/reference/android/os/AsyncTask.html
public interface myInterface{
public abstract void taskComplete(value1,value2... etc);
}

Pass more values in doInBackground AsyncTask Android

How to pass more values in the doInBackground
My AsyncTask looks like this.
private class DownloadFile extends AsyncTask<String, Integer, String> {
#Override
protected String doInBackground(String... sUrl) {
{
}
}
Is it possible somehow to pass more values on my protected String DoInBackground
for example: protected String doInBackground(String... sUrl, String... otherUrl, Context context)
And how to execute the AsyncTask after? new DownloadFile.execute("","",this) or something?
you can send multiple parameters as you can send them as varargs. But you have to use same Type of parameter. So to do what you are trying you can follow any of the followings
Option 1
you can use a setter method to set some value of the class member then use those in doInBackGround. For example
private class DownloadFile extends AsyncTask<String, Integer, String> {
private Context context;
public void setContext(Context c){
context = c;
}
#Override
protected String doInBackground(String... sUrl) {
{
// use context here
}
}
Option 2
Or you can use constructor to pass the values like
private class DownloadFile extends AsyncTask<String, Integer, String> {
private Context context;
public DownloadFile (Context c){
context = c;
}
#Override
protected String doInBackground(String... sUrl) {
{
// use context here
}
}
String... sUrl
the three consecutive dots meaning more then one String. The dots are varargs
And how to pass the Context?
you can force it adding a constructor that takes the Context as parameter:
private Context mContext;
public void setContext(Context context){
if (context == null) {
throw new IllegalArgumentException("Context can't be null");
}
mContext = context;
}
you can do something like this inside your doInBackground method:
String a = sUrl[0]
String b = sUrl[1]
execute AsyncTask in this way:
new DownloadFile().execute(string1,string2);
the first value : sUrl[0] will be the one passed from string1 and
surl[1] will be the second value passed i.e string2 !
Yes you can pass more values in constructor but not in doInBackground
Try this way
new DownloadFile(String sUrl,String other Url,Context context).execute();
Async Task
private class DownloadFile extends AsyncTask<String, Integer, String> {
public DownloadFile(String url,String url2,Context ctx)
{
}
#Override
protected String doInBackground(String... sUrl) {
{
}
}
You cannot, for the following reasons :
protected String doInBackground(String... sUrl, String... otherUrl, Context context)
is not a valid method signature. The dots notations (Varargs) can only be used as the last parameter of the method. This restriction is because otherwise it would make polymorphism much more complex. In fact, how would java know which of your Strings go to sUrl, and which goes to otherUrl?
Moreover, doInBackground overrides a method from AsyncTask. As such, you cannot change the method signature.
What you can do, however, is make those values members of your class and pass in the constructor of your DownloadFile class or add setters to set them before calling execute.
you can use constructor
private class DownloadFile extends AsyncTask<String, Integer, String> {
private Context context;
public void DownloadFile(Context c,String one, int two){
context = c;
}
#Override
protected String doInBackground(String... sUrl) {
{
// use context here
}
}
new DownloadFile().execute(Str1,str2,str3,........);
this is one way to pass more url... if you want send more values in doinbackground method..
public class DownloadFile extends AsyncTask<DataHolders, Integer, String> {
public class DataHolders {
public String url;
public String myval;
}
#Override
protected String doInBackground(DataHolders... params) {
return null;
}
}
you can call the class with
DataHolders mhold = new DataHolders();
new DownloadFile().execute(mhold,mhold2,mhold3,........);
Ypu can create constructor to pass different type parameters and also strings data using String......str
private class DownloadTask extends AsyncTask<String, Integer, String> {
private Context context;
byte[] byteArray;
public DownloadTask (Context c,byte[] byteArray){
context = c;
byteArray=byteArray;
}
#Override
protected String doInBackground(String... str) {
{
// use context here
System.out.println(param[0]);
}
}
new DownloadTask(context,bytearray).excute("xyz");
new DownloadFile().execute("my url","other parameter or url");
private class DownloadFile extends AsyncTask<String, Integer, String> {
#Override
protected String doInBackground(String... sUrl) {
{
try {
return downloadContent(sUrl[0], sUrl[1]); // call
} catch (IOException e) {
return "Unable to retrieve data. URL may be invalid.";
}
}
}

Categories

Resources