首先,我必须声明我是Java的新手。 Android系统。但我确实有基础知识,或者至少可以到达那里。
我的应用目的:在公司,我们有一个SSH服务器远程服务器,并做一些工作。有时,服务器无法访问,因此会中断我们的工作。
我的应用程序假设执行以下操作:
1-使用Jsch,我SSH到服务器,如果有响应,那么,我将在15分钟内再次尝试,如果没有响应,我想通知。
我已经在非Android版本的Java中成功完成了上述操作,并且能够在Android版本中完成,但是在主线程上,因此我无法在UI上更新任何内容。本质上是进度栏.. 在常规版本中,UI冻结,并在下面提供的AsyncTask版本中。我一按下按钮就会出现异常
下面是我正在使用的代码,说实话,我读到了最好的解决方案是AsyncTask,但由于我是新手,我不确定我的错是。老实说,我认为它可能在AsyncTask和AsyncTask中。
我不确定在那里使用什么... 下面是我的代码,希望有人可以指出我的错误。
package com.example.myapp;
import java.io.IOException;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.HandlerThread;
import android.os.StrictMode;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.Toast;
import android.os.Handler;
public class VedasServerMonitorActivity extends Activity {
/** Called when the activity is first created. */
Button button;
EditText IP;
EditText UserName;
EditText Password;
EditText Port;
ProgressBar progressBar1;
String UserStr;
String PassStr;
String IPStr;
int PortInt;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
button = (Button) findViewById(R.id.button1);
IP = (EditText) findViewById(R.id.serverIp);
UserName = (EditText) findViewById(R.id.userName);
Password = (EditText) findViewById(R.id.password);
Port = (EditText) findViewById(R.id.port);
progressBar1 = (ProgressBar) findViewById(R.id.progressBar1);
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
.permitAll().build();
StrictMode.setThreadPolicy(policy);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
new asyncTaskUpdateProgress().execute();
}
});
}
public class asyncTaskUpdateProgress extends AsyncTask<Void, Void, Void> {
@Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
}
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
progressBar1.setVisibility(View.VISIBLE);
UserStr = UserName.getText().toString();
PassStr = Password.getText().toString();
IPStr = IP.getText().toString();
PortInt = Integer.parseInt(Port.getText().toString());
button.setClickable(true);
progressBar1.setVisibility(View.INVISIBLE);
}
@Override
protected void onProgressUpdate(Void... values) {
// TODO Auto-generated method stub
progressBar1.setVisibility(View.INVISIBLE);
}
@Override
protected Void doInBackground(Void... arg0) {
boolean ok = false;
try {
SSHTest sshtest = new SSHTest();
ok = sshtest.sshconnect(UserStr, PassStr, IPStr, PortInt);
}
catch (Exception e) {
e.printStackTrace();
Log.i("ERROR HERE", "doInBackground: IOException");}
if (ok) {
Toast.makeText(getApplicationContext(),
"Connection Susccessfull", Toast.LENGTH_LONG)
.show();
} else {
Toast.makeText(getApplicationContext(),
"Unable to connect", Toast.LENGTH_LONG).show();
notify(getApplicationContext(), true);
}
return null;
}
protected void notify(Context context, Boolean on) {
NotificationManager nm = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
ComponentName comp = new ComponentName(context.getPackageName(),
getClass().getName());
Intent intent = new Intent().setComponent(comp);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
intent, Intent.FLAG_ACTIVITY_NEW_TASK);
Notification n = new Notification(R.drawable.warning, "Message",
System.currentTimeMillis());
n.setLatestEventInfo(context, "Vedas Server Monitor",
"Port Un-rechable", pendingIntent);
nm.notify(22, n);
}
}
}
android×194760
答案 0 :(得分:1)
您需要在doInBackground()
中进行一些更正。但在此之前,关于AsyncTask
的一个小细节。
AsyncTask
。函数onPreExecute()
用于显示任何UI操作
(在大多数情况下,它显示一个对话框)在您输入后台线程之前。函数doInBackground()
用于执行非ui操作(在大多数情况下从服务器获取数据)。在doInBackground()
中执行后台活动时,您可能希望通过使用内部调用publishProgress()
方法的onProgressUpdate()
来显示您所做的一些进展。完成doInBackground()
中的后台活动后,如果您有活动,则会返回活动的result
。在您从doInBackground()
方法内部返回后,会调用onPostExecute()
来接收result
作为参数返回的doInBackground()
。现在onPostExecute()
将在UI线程上运行,并且大多数UI操作(例如在onPreExecute()
中显示对话框,在某些UI组件上显示result
等)都会在此方法中发生。
现在你犯了错误代码:
您正在使用函数toast
显示基于服务器数据提取结果的notification
或notify
,但您仍处于后台非ui线程中。现在,理想情况下应该在onPostExecute()
中返回并检查此结果,并根据其值显示toast
或notification
的UI组件。
我希望这个解释可以帮助您解决问题。
修改强>
在您的情况下,您可以将布尔类型结果变量ok
发送到onPostExecute()
。为此,您需要进行以下更改:
:
public class asyncTaskUpdateProgress extends AsyncTask<Void, Void, Boolean>
和
protected void onPostExecute(Boolean result){
if (ok) {
Toast.makeText(getApplicationContext(),
"Connection Susccessfull", Toast.LENGTH_LONG)
.show();
} else {
Toast.makeText(getApplicationContext(),
"Unable to connect", Toast.LENGTH_LONG).show();
notify(getApplicationContext(), true);
}
}
最后在
protected Void doInBackground(Void... arg0) {
boolean ok = false;
try {
SSHTest sshtest = new SSHTest();
ok = sshtest.sshconnect(UserStr, PassStr, IPStr, PortInt);
}
catch (Exception e) {
e.printStackTrace();
Log.i("ERROR HERE", "doInBackground: IOException");}
return ok;
}
答案 1 :(得分:1)
你可以试试这个
在您的protected void onPreExecute()
中需要添加
progressBar = new ProgressDialog(v.getContext());
progressBar.setCancelable(true);
progressBar.setMessage("File downloading ...");
progressBar.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressBar.setProgress(0);
progressBar.setMax(100);
progressBar.show();
//reset progress bar status
progressBarStatus = 0;
然后
protected void onProgressUpdate(Void... values) {
progressBarStatus= progressBarStatus + x; // x means any value
progressBar.setProgress(progressBarStatus);
}
之后你需要在onPostExecute()
完成progressBar。像
protected void onPostExecute(Void result) {
progressBar.dismiss();
}