Running two classes at the same time in android studio - java

The way that I have my current application set up is that when you press the button then the app displays a counter on the bottom that goes up to ten then stops and then it displays a counter on the top that goes from 10 to 0. However, what I need to do is make these counters happen at the same time. I tried using threads but I think that I must not have been doing it right. Any help would be appreciated.
edit: I want to run mytask and mytask1 at the same time, they currently run after each other
edit2: I was asked for the code for publish progress
protected final void publishProgress(Progress... values) {
if (!isCancelled()) {
getHandler().obtainMessage(MESSAGE_POST_PROGRESS,
new AsyncTaskResult<Progress>(this, values)).sendToTarget();
}
}
Code:
public class MainActivity extends AppCompatActivity {
Button btn;
TextView txt;
Integer count =1;
Integer count1 =10;
TextView txt1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//p
//p
btn = (Button) findViewById(R.id.button);
btn.setText("Start");
txt = (TextView) findViewById(R.id.textView);
txt1 = (TextView) findViewById(R.id.textView2);
View.OnClickListener listener = new View.OnClickListener(){
public void onClick(View view){
count =1;
//p
//p
switch (view.getId()){
case R.id.button:
new MyTask().execute(10);
new MyTask1().execute(0);
break;
}
}
};
btn.setOnClickListener(listener);
}
class MyTask extends AsyncTask<Integer, Integer, String> {
#Override
protected String doInBackground(Integer... params) {
for (; count <= params[0]; count++) {
try {
Thread.sleep(1000);
publishProgress(count);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return "Task Completed.";
}
#Override
protected void onPostExecute(String result) {
txt.setText(result);
btn.setText("Restart");
}
#Override
protected void onPreExecute() {
txt.setText("Task Starting...");
}
#Override
protected void onProgressUpdate(Integer... values) {
txt.setText("BackGround Task Running..."+ values[0]);
}
}
class MyTask1 extends AsyncTask<Integer, Integer, String> {
#Override
protected String doInBackground(Integer... params) {
for (; count1 >= params[0]; count1--) {
try {
Thread.sleep(1000);
publishProgress(count1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return "Task Completed.";
}
#Override
protected void onPostExecute(String result) {
txt1.setText(result);
btn.setText("Restart");
}
#Override
protected void onPreExecute() {
txt1.setText("Task Starting...");
}
#Override
protected void onProgressUpdate(Integer... values) {
txt1.setText("Countdown "+ values[0]);
}
}
}

AsyncTasks are executed on a single thread according to documentation, so that might be the issue.

Related

Runnable not running

I am writing a program that calculates pi with a given amount of iterations. I want to be able to time how long this takes and how much power is being used. I have another version of this application that works perfectly but, with the same code, this version won't.
Most of the code is working fine but the powerRunnable code is not executing when it is called.
any thoughts?
public class MainActivity extends AppCompatActivity {
//GUI
TextView piResultTextView, timeResultTextView,
powerResultTextView, voltageTextView, averageCurrentTextView;
EditText piEditText;
Button calculateButton, stopButton;
TextView countView;
//GLOBAL VARIABLES
Results results;
Handler powerHandler = new Handler();
Runnable powerRunnable = new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), "here", Toast.LENGTH_SHORT).show();
long millis = System.currentTimeMillis() - results.initialTime;
timeResultTextView.setText(getString(R.string.display_time, millis));
double current = getCurrent();
results.totalCurrent += current;
results.count++;
double power = current * results.voltage;
results.powerConsumption += power;
countView.setText(String.valueOf(results.count));
powerHandler.postDelayed(this, 1);
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
piEditText = findViewById(R.id.PiEditText);
calculateButton = findViewById(R.id.CalculateButton);
calculateButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (!empty()) {
results = new Results(getVoltage());
results.initialTime = System.currentTimeMillis();
powerHandler.postDelayed(powerRunnable, 0);
calculatePi(piEditText.getText().toString());
finalizeResults();
displayResults();
}
}
});
stopButton = findViewById(R.id.StopButton);
stopButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
piResultTextView.setText("");
timeResultTextView.setText("");
powerResultTextView.setText("");
voltageTextView.setText("");
averageCurrentTextView.setText("");
powerHandler.removeCallbacks(powerRunnable);
}
});
piResultTextView = findViewById(R.id.PiResultTextView);
timeResultTextView = findViewById(R.id.TimeResultTextView);
powerResultTextView = findViewById(R.id.PowerResultTextView);
voltageTextView = findViewById(R.id.VoltageTextView);
averageCurrentTextView = findViewById(R.id.AverageCurrentTextView);
countView = findViewById(R.id.CountView);
}
#Override
public void onPause() {
super.onPause();
powerHandler.removeCallbacks(powerRunnable);
}
public void finalizeResults() {
results.endTime = System.currentTimeMillis();
powerHandler.removeCallbacks(powerRunnable);
results.powerConsumption *= 1000;
}
public void displayResults() {
piResultTextView.setText(results.pi);
timeResultTextView.setText(getString(R.string.display_time, results.getTime()));
powerResultTextView.setText(getString(R.string.display_power, results.powerConsumption));
voltageTextView.setText(getString(R.string.display_voltage, results.getVoltage()));
averageCurrentTextView.setText(getString(R.string.display_current, results.getAverageCurrent()));
}
}
I try to use your part of code in my application:
Handler powerHandler = new Handler();
Runnable powerRunnable = new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), "here", Toast.LENGTH_SHORT).show();
powerHandler.postDelayed(this, 1);
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
ButterKnife.bind(this);
powerHandler.postDelayed(powerRunnable, 0);
}
And its working.

AsyncTask block Unity(UI) thread issue

Here is my main Activity in OnCreate:
mUnityPlayer = new UnityPlayer(this);
setContentView(mUnityPlayer);
mUnityPlayer.requestFocus();
new SimuDownloadTask(this).execute();
The following code is the source code of SimuDownloadTask:
public class SimuDownloadTask extends AsyncTask<Void, Integer, Boolean> {
private ProgressDialog progressDialog;
private int count=0;
private Context mainActivityContext;
public SimuDownloadTask(Context context) {
mainActivityContext=context;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog=new ProgressDialog(mainActivityContext,R.style.XMNewDialog);
progressDialog.show();
}
#Override
protected Boolean doInBackground(Void... arg0) {
while(true)
{
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int downloadPercent=doDownload();
publishProgress(downloadPercent);
if(downloadPercent>=500)
break;
}
return true;
}
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
progressDialog.setMessage("current progress:"+values[0]+"%");
}
#Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
progressDialog.dismiss();
if(result)
{
Toast.makeText(mainActivityContext, "success", Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(mainActivityContext, "fail", Toast.LENGTH_SHORT).show();
}
}
private int doDownload()
{
count+=1;
return count;
}
}
Here is the problem. When I start the app, the progressbar blocks the UI thread.
After the progressbar finished, the Unity starts.
When I replace the SimuDownloadTask in OnCreate with the following code:
new Thread(){
#Override
public void run() {
super.run();
Looper.prepare();
progressDialog=new ProgressDialog(UnityPlayerActivity.this,R.style.XMNewDialog);
progressDialog.setTitle("test");
progressDialog.setCancelable(true);
progressDialog.show();
Looper.loop();
}
}.start();
The unity thread is running properly(not blocked by the progressbar). So I think the problem is not relevant to Unity.
I have already checked the relevant links such as:
Asynctask from non ui thread
But still can't figure out the issues.
Any clues will be helpful.
Instead of using an AsyncTask you may use a worker thread for the counter logic and a handler to update the progress bar.
See the updated answer in this link

Android move from one activity to another

I was having some problem for Android activity transition. Basically what I am trying to do is share text to Twitter. However, when I open up the twitter content, it took quite a few seconds to load up the content and resulting in the white blank activity for a few seconds.
And here is my codes, when my button onClick, I am executing the loading dialog:
ivTwitterShare.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Thread newThread = new Thread() {
#Override
public void run() {
try {
super.run();
sleep(10000);
} catch (Exception e) {
} finally {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri
.parse(tweetUrl));
startActivity(intent);
progressDialog.dismiss();
}
}
};
newThread.start();
new LoadTwitterTask().execute();
}
});
private class LoadTwitterTask extends AsyncTask<Void, Integer, Void> {
#Override
protected void onPreExecute() {
progressDialog = ProgressDialog.show(context, "Loading Twitter...",
"Retrieving Twitter information, please wait...", false,
false);
EventDialogueBox.customizeDialogueBox(context, progressDialog);
}
#Override
protected Void doInBackground(Void... params) {
try {
synchronized (this) {
int counter = 0;
while (counter <= 4) {
this.wait(50);
counter++;
publishProgress(counter * 25);
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onProgressUpdate(Integer... values) {
progressDialog.setProgress(values[0]);
}
#Override
protected void onPostExecute(Void result) {
}
}
However, my problem now is the white blank page before the content is loaded up still there. What I wanted is firstly, the loading dialog will show. Then, at the same time, the twitter intent is loading. Once finish loaded up the content, then dialog will be dismissed.
Any ideas?
Thanks in advance.

Android AsyncTask runs multiple times

In my app ,there is an one button which get input from database.When I press it more than one in a short time it crashes.
How can i avoid this error with using asynctask?
show.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
showinf();
}
});
}
private String[] columns={"name","surname"};
private void showinf(){
SQLiteDatabase db=v1.getReadableDatabase();
Cursor c=db.query("infos",columns,null,null, null,null,null);
Random mn2=new Random();
int count=c.getCount();
String mn=String.valueOf(count);
int i1=mn2.nextInt(count+1);
c.move(i1);
t1.setText(c.getString(c.getColumnIndex("name")));
t2.setText(c.getString(c.getColumnIndex("surname")));
}
thanks...
You can create a boolean flag (let's say bDiscardButtonAction), and set it to true in onPreExecute() and set it to false in onPostExecute(), something like:
public class FooTask extends AsyncTask<Foo, Foo, Foo>
{
private static boolean bDiscardButtonAction = false;
private boolean isDiscareded = false;
#Override
public void onPreExecute()
{
if(bDiscardButtonAction)
{
isDiscareded = true;
return;
}
bDiscardButtonAction = true;
}
#Override
public Foo doInBackground(Foo... params)
{
if(isDiscareded) return;
// ...
}
#Override
public void onPostExecute(Void result)
{
if(!isDiscareded) bDiscardButtonAction = false;
}
#Override
public void onCancelled(Foo result)
{
if(!isDiscareded) bDiscardButtonAction = false;
}
}
disable the show button in onPreExecute() and enable it back onPostExecute().
public class getAsyncDataTask extends AsyncTask<Void, Void, Void>
{
#Override
public void onPreExecute()
{
show.setAlpha(0.5);
show.setEnable(false);
}
#Override
public void doInBackground(Void... params)
{
//retrieve the data from db;
}
#Override
public void onPostExecute()
{
show.setAlpha(1.0);
show.setEnable(true);
}
}
I hope this code will help u out.
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
new AsynchTaskManualLocation().execute();
});
public class AsynchTaskGetData extends AsyncTask<String,Void,String>
{
#Override
protected String doInBackground(String... url) {
//showinf(); this method contains operation of getting data from //database OR ur logic to getdata
return showinf();
}
#Override
protected void onPostExecute(String result) {
//here u get result in resul var and process the result here
}
}
}

Android dialog box and Async Tasks

I am trying to make a progress dialog that pop up while things are loading. I have figured out how to make dialog boxes appear and disappear and can change whats in them but I have multiple async tasks and want the dialog to appear when the first async task starts and then disappear when the last async tasks finishes.
Is there a way for the dialogs to know when all async tasks are complete for a given activity? I am having problems on how to approach this issue. Thanks for the help!
Here is a exact sample code which i used to acheive the same functionality.
public class LoginActivity extends Activity
{
public static String TAG = "Login_Activity: ";
private EditText usernameEditText;
private EditText passwordEditText;
private ProgressDialog progress_dialog;
private int taskCount = 0;
private void updateTaskCount(int value)
{
taskCount += value;
if(progress_dialog != null && taskCount == 0)
{
progress_dialog.dismiss();
}
}
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
usernameEditText = (EditText) findViewById(R.id.login_username);
passwordEditText = (EditText) findViewById(R.id.login_password);
progress_dialog = new ProgressDialog(this);
}
public void LoginClick(View view)
{
String URL = "http://SOME.com/api/Members?Username=" +
usernameEditText.getText().toString()+ "&Password=" +
passwordEditText.getText().toString();
progress_dialog.setMessage("Authenticating. Please wait...");
progress_dialog.setCancelable(false);
progress_dialog.show();
new AuthenticateUserFromServer().execute(URL);
updateTaskCount(1);
new NotifyWebService ().execute("some other url");
updateTaskCount(1);
}
protected void onDestroy()
{
progress_dialog.dismiss();
super.onDestroy();
}
#Override
protected void onPause()
{
progress_dialog.dismiss();
super.onPause();
}
private class AuthenticateUserFromServer extends AsyncTask <String, Void, String>
{
protected String doInBackground(String... urls)
{
return Utility.readJSONFromWebService(urls[0]);
}
protected void onPostExecute(String result)
{
// do other stuff
updateTaskCount(-1);
}
}
private class NotifyWebService extends AsyncTask <String, Void, String>
{
protected String doInBackground(String... urls)
{
return Utility.readJSONFromWebService(urls[0]);
}
protected void onPostExecute(String result)
{
// do other stuff
updateTaskCount(-1);
}
}
}
If you have multiple/separate classes for async tasks you can create a static utility class to keep track of and update count.

Categories