ProgressDialog 未在主线程中启动 [英] ProgressDialog not getting started in main thread

查看:39
本文介绍了ProgressDialog 未在主线程中启动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我制作了一个应用程序,可以将一些数据上传到我的数据库.在 Activity 中,用户将输入要上传的数据,我创建了一个 ProgressDialog.ProgressDialog 是在 onClick() 方法中创建的.

理论上,它会被创建,因为我不会尝试在主 UI 线程以外的线程中创建 ProgerssDialog.仍然,它没有被显示.我不知道为什么.

package com.example.demoapp;导入 android.widget.*;导入 android.app.Activity;导入 android.app.ProgressDialog;导入 android.content.Intent;导入 android.content.SharedPreferences;导入 android.os.Bundle;导入 android.os.Handler;导入 android.os.Message;导入 android.util.Log;导入 android.view.View;导入 android.view.View.OnClickListener;导入 android.widget.Toast;公共类 MainActivity 扩展 Activity 实现 OnClickListener{私有 EditText planID、姓名、号码、地址、handlerValue、planAmount、有效性、pass、confirm_pass;私人按钮调用;私有 SharedPreferences 首选项;私有 SharedPreferences.Editor 编辑器;私人字符串响应;@覆盖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);如果(启动){planID = (EditText) findViewById(R.id.planIDET);name = (EditText) findViewById(R.id.nameET);number = (EditText) findViewById(R.id.contactET);地址 = (EditText) findViewById(R.id.addressET);手机值 = (EditText) findViewById(R.id.handsetValueET);planAmount = (EditText) findViewById(R.id.planAmountET);有效性 = (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("");手机值.setText("");planAmount.setText("");有效性.setText("");pass.setText("");Confirm_pass.setText("");call.setOnClickListener(this);}别的{Intent intent = new Intent(this, LoginActivity.class);开始活动(意图);结束();}}@覆盖public void onClick(View v) {if(pass.getText().toString().equals(confirm_pass.getText().toString())){ProgressDialog progress = ProgressDialog.show(v.getContext(), "请稍候...", "连接到服务器", true, true);String query = "INSERT INTO user_info (name, password, address, plan_id, contact,handhand_value, plan_amount,validity) "+ "VALUES('" + name.getText() + "','"+ pass.getText() +"','" + address.getText() + "','" + planID.getText() + "','" + number.getText() + "','" + handsValue.getText() + "','" + planAmount.getText() + "','" + Effectiveness.getText() + "');";ConnectDBThread connect = new ConnectDBThread(query, Resources.INSERT);线程 t1 = 新线程(连接);t1.start();//##################################//Log.i("onClick() ThreadName",String.valueOf(Thread.currentThread().getId()));同时(真){尝试 {线程睡眠(100);} catch (InterruptedException e){e.printStackTrace();}if(Resources.serverResponse!=null){Toast.makeText(this, "注册成功", 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();//--- 进度条停止进展.解雇();休息;}}//环形}别的Toast.makeText(this, "密码不匹配!", Toast.LENGTH_LONG).show();}//onClick()}

这里,ConnectDBThread 是 Runnable 接口的实现,它连接到服务器并随数据一起发布查询.

如果我在 onClick() 中的 If 语句之外创建了 ProgressDialog,则应用程序首先执行查询.查询完成后显示ProgressDialog.

请帮帮我.谢谢.

解决方案

我认为问题在于 ProgressDialog 的上下文.从设计的角度来看,我认为将 ProgressDialog 声明为实例变量会更好.

public class YourClass{私人 ProgressDialog 进度对话框;//实例变量....}

然后在点击方法中像这样创建它:

//我认为主要问题在于您绑定到 progressDialog 的上下文//提供 Activity 作为上下文,因为 Activity 扩展了 ContextprogressDialog= ProgressDialog.show(this, "请稍候...", "正在连接服务器", true, true);

最后不要在 onClick 方法中放置像这样的 while 循环.它会导致按钮变得不受欢迎,并且还会使 UI 无响应.将您的 ConnectDBThread 设为 AsyncTask,并在 doInBackground 中完成后台进程后,通过 onPostExecute 从那里更新 UI(如关闭对话框).>

这是一个建议的解决方案:

public class InsertTask extends AsyncTask{ProgressDialog 对话框;上下文 ctx;公共插入任务(上下文 ctx){this.ctx = ctx;}protected void onPreExecute(Void 结果) {//在这里做 UI 工作dialog = ProgressDialog.show(ctx, "请稍候...", "连接到服务器", true, true);}受保护的 Void doInBackground(String... args) {//在这里做插入操作...字符串用户名 = args[0];字符串密码 = args[1];......String query = ....//生成查询String serverResponse = doDBInsert(query);//创建一个方法来运行查询并返回响应返回服务器响应;}protected void onPostExecute(String result) {//在这里做 UI 工作//如果需要,在某处显示您的 serverResponse(result)if(dialog!=null && dialog.isShowing()){dialog.dismiss();}}}

onClick 方法内部:

//如果满足校验条件(密码=确认密码)new InsertTask(getApplicationContext()).execute(username, password, address ...);

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.

解决方案

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 ...);

这篇关于ProgressDialog 未在主线程中启动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆