Java Android-如何持续提示对话框 介绍
我想要完成的事情[听起来]很简单。我想用登录对话框提示用户,直到用户成功进行身份验证 我计划使用AsyncTask来处理数据和web请求,但这很快就变成了一场噩梦;很可能是因为我缺乏安卓系统的经验 然而,我知道这是可以做到的,就像我以前在其他应用程序中看到的那样Java Android-如何持续提示对话框 介绍,java,android,http,android-asynctask,android-dialog,Java,Android,Http,Android Asynctask,Android Dialog,我想要完成的事情[听起来]很简单。我想用登录对话框提示用户,直到用户成功进行身份验证 我计划使用AsyncTask来处理数据和web请求,但这很快就变成了一场噩梦;很可能是因为我缺乏安卓系统的经验 然而,我知道这是可以做到的,就像我以前在其他应用程序中看到的那样 我想要完成的 问题是怎么做?我知道我想做什么: 1. Initially prompt a user to login. 2. Send authentication data. 3. If successful, continue
我想要完成的 问题是怎么做?我知道我想做什么:
1. Initially prompt a user to login.
2. Send authentication data.
3. If successful, continue the application.
4. If unsuccessful, reprompt the user until success.
到目前为止我所拥有的 到目前为止,我拥有的是AsyncTask(
LoginTask
),它将处理web请求和登录数据:
public class LoginTask extends AsyncTask<String, Void, App.STATUS>
{
private boolean m_proceed = false;
private String m_username, m_key;
@Override
protected void onPreExecute()
{
// Check if there is a dialog on screen. //
m_proceed = !App.DIALOG_ONSCREEN;
}
@Override
protected App.STATUS doInBackground(String ... p_args)
{
// Do not do this if a dialog is on screen. //
if(!m_proceed)
return App.STATUS.DENIED;
// Make a web request. //
try
{
URL t_url = new URL("https://mysite.com/api/login");
HttpsURLConnection t_con = (HttpsURLConnection)t_url.openConnection();
t_con.setRequestMethod("POST");
t_con.setRequestProperty("User-Agent", "Mozilla/5.0");
t_con.setDoOutput(true);
DataOutputStream t_wr = new DataOutputStream(t_con.getOutputStream());
t_wr.writeBytes("username="+p_args[0]+"&password="+p_args[1]);
t_wr.flush();
t_wr.close();
t_con.connect();
BufferedReader t_in = new BufferedReader(new InputStreamReader(t_con.getInputStream()));
String t_input_line;
StringBuffer t_response = new StringBuffer();
while((t_input_line = t_in.readLine()) != null)
{
t_response.append(t_input_line);
}
t_in.close();
// If denied, return failed. If accepted, set the username and key. //
if(t_response.toString().equals("DENIED"))
return App.STATUS.FAILED;
else
{
m_key = t_response.toString();
m_username = p_args[0];
}
return App.STATUS.ACCEPTED;
}
catch(Exception err)
{
System.err.println(err.getMessage());
}
return App.STATUS.FAILED;
}
@Override
protected void onPostExecute(App.STATUS p_status)
{
// Authenticate the user if the username and key are valid. //
if(p_status == App.STATUS.ACCEPTED)
App.acceptCredentials(m_username, m_key);
// The dialog is no longer on the screen. //
App.DIALOG_ONSCREEN = false;
}
}
我需要什么帮助 我的主要问题是如何设计我的程序,以便在用户成功验证之前可以轻松地一直显示登录对话框?我曾想过使用while循环,但这样会一直显示对话框并影响性能。当异步和同步任务同时工作时,这是相当棘手的 我不是在寻找直截了当的代码,但如果您能了解一般情况,我将不胜感激 感谢您花时间阅读本文,并感谢您的帮助
解决方案
HomeActivity.java
private void promptLogin()
{
final Context t_main_context = this;
// Create the dialog. //
LayoutInflater t_infl = LayoutInflater.from(this);
final View t_login_view = t_infl.inflate(R.layout.login_dialog, null);
final AlertDialog t_dialog = new AlertDialog.Builder(this)
.setTitle("Login")
.setCancelable(false)
.setView(t_login_view)
.setPositiveButton("Login", null)
.create();
t_dialog.show();
t_dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View t_view)
{
String t_username = ((EditText)t_login_view.findViewById(R.id.in_username)).getText().toString(),
t_password = ((EditText)t_login_view.findViewById(R.id.in_password)).getText().toString();
try
{
new LoginTask(t_main_context, t_dialog).execute(t_username, t_password);
}
catch(Exception err)
{
err.printStackTrace();
}
}
});
}
@Override
public void onCreate(Bundle p_data)
{
// Basic crap... //
super.onCreate(p_data);
setContentView(R.layout.activity_home);
// Are we authenticated? //
if(!App.isAuthenticated())
promptLogin();
}
private String m_username, m_key;
private Context m_context;
private AlertDialog m_dialog;
private ProgressDialog m_loading;
public LoginTask(Context p_context, AlertDialog p_dialog)
{
m_context = p_context;
m_dialog = p_dialog;
m_loading = ProgressDialog.show(m_context, "", "Logging in...", true);
}
@Override
protected App.STATUS doInBackground(String ... p_args)
{
// Make a web request. //
try
{
URL t_url = new URL("https://mysite.com/api/login");
HttpsURLConnection t_con = (HttpsURLConnection)t_url.openConnection();
t_con.setRequestMethod("POST");
t_con.setRequestProperty("User-Agent", "Mozilla/5.0");
t_con.setDoOutput(true);
DataOutputStream t_wr = new DataOutputStream(t_con.getOutputStream());
t_wr.writeBytes("username="+p_args[0]+"&password="+p_args[1]);
t_wr.flush();
t_wr.close();
t_con.connect();
BufferedReader t_in = new BufferedReader(new InputStreamReader(t_con.getInputStream()));
String t_input_line;
StringBuffer t_response = new StringBuffer();
while((t_input_line = t_in.readLine()) != null)
{
t_response.append(t_input_line);
}
t_in.close();
// If denied, return failed. If accepted, set the username and key. //
if(t_response.toString().equals("DENIED"))
return App.STATUS.FAILED;
else
{
m_key = t_response.toString();
m_username = p_args[0];
}
return App.STATUS.ACCEPTED;
}
catch(Exception err)
{
System.err.println(err.getMessage());
}
return App.STATUS.FAILED;
}
@Override
protected void onPostExecute(App.STATUS p_status)
{
m_loading.dismiss();
// Authenticate the user if the username and key are valid. //
if(p_status == App.STATUS.ACCEPTED)
{
App.acceptCredentials(m_username, m_key);
m_dialog.dismiss();
}
else
Toast.makeText(m_context, "Login failed", Toast.LENGTH_SHORT).show();
}
LoginTask.java
private void promptLogin()
{
final Context t_main_context = this;
// Create the dialog. //
LayoutInflater t_infl = LayoutInflater.from(this);
final View t_login_view = t_infl.inflate(R.layout.login_dialog, null);
final AlertDialog t_dialog = new AlertDialog.Builder(this)
.setTitle("Login")
.setCancelable(false)
.setView(t_login_view)
.setPositiveButton("Login", null)
.create();
t_dialog.show();
t_dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View t_view)
{
String t_username = ((EditText)t_login_view.findViewById(R.id.in_username)).getText().toString(),
t_password = ((EditText)t_login_view.findViewById(R.id.in_password)).getText().toString();
try
{
new LoginTask(t_main_context, t_dialog).execute(t_username, t_password);
}
catch(Exception err)
{
err.printStackTrace();
}
}
});
}
@Override
public void onCreate(Bundle p_data)
{
// Basic crap... //
super.onCreate(p_data);
setContentView(R.layout.activity_home);
// Are we authenticated? //
if(!App.isAuthenticated())
promptLogin();
}
private String m_username, m_key;
private Context m_context;
private AlertDialog m_dialog;
private ProgressDialog m_loading;
public LoginTask(Context p_context, AlertDialog p_dialog)
{
m_context = p_context;
m_dialog = p_dialog;
m_loading = ProgressDialog.show(m_context, "", "Logging in...", true);
}
@Override
protected App.STATUS doInBackground(String ... p_args)
{
// Make a web request. //
try
{
URL t_url = new URL("https://mysite.com/api/login");
HttpsURLConnection t_con = (HttpsURLConnection)t_url.openConnection();
t_con.setRequestMethod("POST");
t_con.setRequestProperty("User-Agent", "Mozilla/5.0");
t_con.setDoOutput(true);
DataOutputStream t_wr = new DataOutputStream(t_con.getOutputStream());
t_wr.writeBytes("username="+p_args[0]+"&password="+p_args[1]);
t_wr.flush();
t_wr.close();
t_con.connect();
BufferedReader t_in = new BufferedReader(new InputStreamReader(t_con.getInputStream()));
String t_input_line;
StringBuffer t_response = new StringBuffer();
while((t_input_line = t_in.readLine()) != null)
{
t_response.append(t_input_line);
}
t_in.close();
// If denied, return failed. If accepted, set the username and key. //
if(t_response.toString().equals("DENIED"))
return App.STATUS.FAILED;
else
{
m_key = t_response.toString();
m_username = p_args[0];
}
return App.STATUS.ACCEPTED;
}
catch(Exception err)
{
System.err.println(err.getMessage());
}
return App.STATUS.FAILED;
}
@Override
protected void onPostExecute(App.STATUS p_status)
{
m_loading.dismiss();
// Authenticate the user if the username and key are valid. //
if(p_status == App.STATUS.ACCEPTED)
{
App.acceptCredentials(m_username, m_key);
m_dialog.dismiss();
}
else
Toast.makeText(m_context, "Login failed", Toast.LENGTH_SHORT).show();
}
因此,我在HomeActivity.java
中的PrompLogin()
中所做的是,我覆盖了ClickListener上的按钮,这样对话框将不会关闭,除非通过t\u dialog.dismise()关闭。然后,我将web请求发送到LoginTask
,并将对话框作为参数传递,这样对话框只会在我取消对话框之前关闭
我仅在接受凭据时才关闭该对话框,如您在onPostExecute()
中所见
这样,对话框将一直显示在屏幕上,直到用户成功登录为止,这就是我一直在寻找的行为
谢谢大家的帮助 您必须创建一个活动来处理您的登录,另一个活动是您的主要活动。如果登录失败,则什么也不会发生,如果登录成功,则启动第二个活动。不需要复杂的设置。
您还可以查看Volley库,它使http连接非常容易。1。最初提示用户登录。
在此处不断提示对话框,并使用setCancelable(false)
,这样用户就不会取消登录过程。然后在按钮上创建一个视图。OnclickListner
,用户必须单击该按钮才能将数据发送到服务器。让我们说一下Login
按钮
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Delete entry")
.setMessage("Are you sure you want to delete this entry?")
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// send data here with AsyncTask
}
})
.setIcon(R.drawable.ic_my_icon);
builder.setCancelable(false);
builder.show();
protected void onPostExecute(Boolean result) {
if(result) {
// he is now authenticated, dismiss dialog and continue in your app
dialog.dismiss();
} else {
// nothing to do, until he succeed
}
}
2。发送身份验证数据。
在这里使用您的AsyncTask
,在doInBackgroud()
方法中执行发送任务,并返回一些onPostExecute()
以了解身份验证是否成功。如果成功,则关闭对话框;如果失败,则保留对话框,等待用户再次单击登录
按钮
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Delete entry")
.setMessage("Are you sure you want to delete this entry?")
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// send data here with AsyncTask
}
})
.setIcon(R.drawable.ic_my_icon);
builder.setCancelable(false);
builder.show();
protected void onPostExecute(Boolean result) {
if(result) {
// he is now authenticated, dismiss dialog and continue in your app
dialog.dismiss();
} else {
// nothing to do, until he succeed
}
}
3。如果成功,请继续应用程序。
使用disclose()
方法关闭此处的对话框
4。如果失败,请重新提示用户直到成功。
在验证过程成功之前,不要执行任何操作,让对话框显示出来。您还可以向用户显示一些内容(祝酒词、图片等),告诉他尚未登录
希望你明白。谢谢!我将尝试实现这一点,并向您通报情况。继续提示此处的对话框
等等,我是否应该使用while循环?阅读4。如果不成功,请重新提示用户直到成功
部分。您只需要显示一次对话框。然后让用户输入登录信息,如果正确,关闭对话框,否则显示!!我接受这是正确的答案,因为它给了我一些见解,但完整的解决方案列在OP中。感谢您的回答!我想我可以使用我的Http连接方法,它已经工作了:)至于你告诉我如何设置我的活动来处理登录,我知道这将是最简单的,但我想做一些看起来很流畅的事情。要登录的整个活动?我个人认为这很笨拙。再说一次,如果我不能让整个对话顺利进行,我会退回到对话中去。@Ken即使有些东西能正常工作,但并不意味着这是最好的方式。使用现成的框架(如Volley)将帮助您更易于阅读和编写,而不是使用您自己编写的代码,但这当然是一个品味问题。您为什么要使用对话框
?它在你的应用程序中添加了什么,而一个简单的登录屏幕并没有添加什么?我认为你试图添加一个对话框作为登录名,这让事情变得更难了。@Darwind我很欣赏你的见解,但我不认为事情很难,我就不应该这样做。我是说你不应该这样做,因为它很难,因为它不难。我只是觉得你让事情变得更难了。当你已经有了可以使用的活动时,使用对话框作为登录屏幕是没有意义的。虽然对话框在网站上很有用,但我相信你不应该在移动应用程序中使用它们。