【问题标题】:Using AsynTask to show progress bar while attempting to SSH to Server尝试 SSH 到服务器时使用 AsyncTask 显示进度条
【发布时间】:2012-06-24 05:50:04
【问题描述】:

首先,我必须声明我是 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);
        }

    }

}

机器人× 194760

【问题讨论】:

    标签: android android-asynctask android-progressbar


    【解决方案1】:

    您需要在doInBackground() 中进行一些更正。但在此之前,有一个关于AsyncTask 的小细节。

    AsyncTask 在您有任何非 UI 后台活动要执行时使用。函数onPreExecute() 用于显示任何 UI 动作 (在大多数情况下,它会显示一个对话框)在您进入后台线程之前。函数doInBackground() 用于执行非ui 操作(在大多数情况下从服务器获取数据)。在doInBackground() 中进行后台活动时,您可能希望通过使用publishProgress() 来显示您所做的一些进展,这将在内部调用onProgressUpdate() 方法。在doInBackground() 中的后台活动完成后,您将返回活动的result(如果有)。在您从内部的doInBackground() 方法返回后,会调用onPostExecute(),它将接收您在doInBackground() 中返回的result 作为参数。现在onPostExecute() 将在 UI 线程上运行,并且大多数 UI 操作(如在onPreExecute() 中显示的对话框的关闭、在某些 UI 组件上显示 result 等)都发生在此方法中。

    现在你在代码中犯的错误: 您正在根据使用函数notify 获取服务器数据的结果显示toastnotification,但您仍处于后台非ui 线程中。现在这个结果应该在理想情况下返回并在onPostExecute() 中检查,并根据其值显示toastnotification 的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;
    
     }
    

    【讨论】:

    • Arun,谢谢,您的高级解释真的很有帮助。然而,我唯一的问题是进入代码:)......是的,我是一个新手,但从你所说的关于 toast 和通知的内容来看,如果我暂时评论它们,它还会显示进度条吗?我遇到的另一个问题是要通过什么以及如何通过?示例:受保护的 Void doInBackground(Void...arg0) 我是否应该将其保留为 void ...args0? (这是我也迷路了
    • 在扩展 AsyncTask 时,您指定 3 个参数类型,例如 AsyncTask&lt;Params, Progress, Result&gt;,其中 Params 是您发送到 doInBackground() 的参数类型,Progress 是您发送到 @987654353 的参数类型@ 和 Result 用于 onPreExecute()
    • 我会尝试并返回结果。感谢您的支持。非常有帮助和清晰,我现在了解 AsyncTask 感谢您
    • 越来越近,只有受保护的 Void doInBackground(Void... arg0) { ......return ok;这是一个无效的返回类型。
    • 好的,我将 Void doInBackground(Void...arg0) 更改为 Boolean doInBackground(Void...arg0) { 但是我遇到了与处理程序有关的异常,粘贴在 06-24 22 下面:08:29.717: WARN/System.err(13570): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() com.example.myapp.VedasServerMonitorActivity$asyncTaskUpdateProgress..... ......................
    【解决方案2】:

    你可以试试这个
    在你的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() 中完成您的进度条。喜欢

    protected void onPostExecute(Void result) {
            progressBar.dismiss();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-16
      • 2016-06-11
      • 2013-08-06
      • 2020-03-13
      • 1970-01-01
      • 1970-01-01
      • 2013-06-27
      • 1970-01-01
      相关资源
      最近更新 更多