问题
I made an app which can upload some data to my database. In Activity, in which the user will enter data to be uploaded, i created a ProgressDialog. The ProgressDialog is created inside the onClick() method.
In theory, it will be created because I'm not trying to make a ProgerssDialog in a thread other than Main UI Thread. Still, it's not being shown. I don't know why.
package com.example.demoapp;
import android.widget.*;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Toast;
public class MainActivity extends Activity implements OnClickListener{
private EditText planID, name, number, address, handsetValue, planAmount, validity, pass, confirm_pass;
private Button call;
private SharedPreferences prefs;
private SharedPreferences.Editor editor;
private String response;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
prefs = getSharedPreferences("PREF", MODE_PRIVATE);
boolean startup = prefs.getBoolean("FIRST_STARTUP", true);
if(startup)
{
planID = (EditText) findViewById(R.id.planIDET);
name = (EditText) findViewById(R.id.nameET);
number = (EditText) findViewById(R.id.contactET);
address = (EditText) findViewById(R.id.addressET);
handsetValue = (EditText) findViewById(R.id.handsetValueET);
planAmount = (EditText) findViewById(R.id.planAmountET);
validity = (EditText) findViewById(R.id.validityET);
pass = (EditText) findViewById(R.id.editText1);
confirm_pass = (EditText) findViewById(R.id.editText2);
call = (Button) findViewById(R.id.submit_Button);
planID.setText("");
name.setText("");
number.setText("");
address.setText("");
handsetValue.setText("");
planAmount.setText("");
validity.setText("");
pass.setText("");
confirm_pass.setText("");
call.setOnClickListener(this);
}
else
{
Intent intent = new Intent(this, LoginActivity.class);
startActivity(intent);
finish();
}
}
@Override
public void onClick(View v) {
if(pass.getText().toString().equals(confirm_pass.getText().toString()))
{
ProgressDialog progress = ProgressDialog.show(v.getContext(), "Please wait...", "Connecting to server", true, true);
String query = "INSERT INTO user_info (name, password, address, plan_id, contact, handset_value, plan_amount, validity) "
+ "VALUES('" + name.getText() + "','"+ pass.getText() +"','" + address.getText() + "','" + planID.getText() + "','" + number.getText() + "','" + handsetValue.getText() + "','" + planAmount.getText() + "','" + validity.getText() + "');";
ConnectDBThread connect = new ConnectDBThread(query, Resources.INSERT);
Thread t1 = new Thread(connect);
t1.start();
//####################################//
Log.i("onClick() ThreadName",String.valueOf(Thread.currentThread().getId()));
while(true)
{
try {
Thread.sleep(100);
} catch (InterruptedException e)
{e.printStackTrace();}
if(Resources.serverResponse!=null)
{
Toast.makeText(this, "Registered Successfully", Toast.LENGTH_LONG).show();
Log.i("SERVER", Resources.serverResponse);
prefs = getSharedPreferences("PREF", MODE_PRIVATE);
editor = prefs.edit();
editor.putBoolean("FIRST_STARTUP", false);
editor.putString("USERNAME", name.getText().toString());
editor.putString("USERPASS", pass.getText().toString());
editor.commit();
//--- PROGRESSBAR STOPPED
progress.dismiss();
break;
}
}//LOOP
}
else
Toast.makeText(this, "Password mismatch!", Toast.LENGTH_LONG).show();
}// onClick()
}
Here, ConnectDBThread is an implementation of Runnable interface which connects to the server and posts a query along with data.
If I created ProgressDialog outside of If statement in onClick(), then app executes query first. After completion of query, it shows ProgressDialog.
Please help me. Thank you.
回答1:
I think the problem is with the context of the ProgressDialog. From design perspective I believe it is better to declare the ProgressDialog as an instance variable.
public class YourClass{
private ProgressDialog progressDialog; // instance variable
....
}
And then in the click method create it like this:
// I believe the main issue is with the context you bind to the progressDialog
// provide the activity as context as an Activity extends Context
progressDialog= ProgressDialog.show(this, "Please wait...", "Connecting to server", true, true);
And lastly do not put a while loop like that inside the onClick method. It will cause the button to be sticky which is not desired and will also make UI unresponsive. Make your ConnectDBThread an AsyncTask and update the UI (like dismiss the dialog) from there through onPostExecute once background process is completed in doInBackground.
Here is a proposed solution:
public class InsertTask extends AsyncTask<String, Void, String> {
ProgressDialog dialog;
Context ctx;
public InsertTask(Context ctx){
this.ctx = ctx;
}
protected void onPreExecute(Void result) {
// do UI work here
dialog = ProgressDialog.show(ctx, "Please wait...", "Connecting to server", true, true);
}
protected Void doInBackground(String... args) {
// do insert operation here ...
String username = args[0];
String password = args[1];
......
String query = .... // generate the query
String serverResponse = doDBInsert(query); // create a method to run the query and return response
return serverResponse;
}
protected void onPostExecute(String result) {
// do UI work here
// display your serverResponse(result) somewhere if needed
if(dialog!=null && dialog.isShowing()){
dialog.dismiss();
}
}
}
Inside onClick Method:
//If check condition is met (password = confirm password)
new InsertTask(getApplicationContext()).execute(username, password, address ...);
来源:https://stackoverflow.com/questions/27691797/progressdialog-not-getting-started-in-main-thread