【问题标题】:Parameter passed from callee but comes as null in the method definition从被调用者传递的参数,但在方法定义中为 null
【发布时间】:2018-09-12 04:20:18
【问题描述】:

我基本上是在尝试创建一个解压缩函数。我在下面的块中调用了带有参数的函数:

UnzipUtility unzipUtility = new UnzipUtility();
    try {
        unzipUtility.unzip(localFilePath, parentPath);
    } catch (IOException e) {
        e.printStackTrace();
    }

该方法的定义是在一个类UnzipUtility中,代码如下:

    public void unzip(String zipFilePath, String destDirectory) throws IOException {
    File destDir = new File(destDirectory);
    if (!destDir.exists()) {
        destDir.mkdir();
    }
    ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFilePath));
    ZipEntry entry = zipIn.getNextEntry();
    // iterates over entries in the zip file
    while (entry != null) {
        String filePath = destDirectory + File.separator + entry.getName();
        if (!entry.isDirectory()) {
            // if the entry is a file, extracts it
            extractFile(zipIn, filePath);
        } else {
            // if the entry is a directory, make the directory
            File dir = new File(filePath);
            dir.mkdir();
        }
        zipIn.closeEntry();
        entry = zipIn.getNextEntry();
    }
    zipIn.close();
}

但是在运行时,虽然参数在主类中正确传递,但是在 unzip 方法中值显示为 null。

请帮忙解决一下

主要类如下:

package com.example.sftpconnection;
import android.annotation.SuppressLint;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.SftpException;


//import java.io.BufferedOutputStream;
import java.io.File;
//import java.io.FileOutputStream;
import java.io.IOException;
//import java.io.OutputStream;
import java.util.List;
import com.example.sftpconnection.UnzipUtility;

public class SFTPActivity extends AppCompatActivity {

    private String fileName = "1234.zip";
    private String localFilePath;
    private String parentPath;
    @SuppressLint("StaticFieldLeak")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sftp);


        new AsyncTask<Void, Void, List<String>>() {
            @Override
            protected List<String> doInBackground(Void... params) {
                try {
                    Downloader(fileName);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return null;
            }

        }.execute();

        UnzipUtility unzipUtility = new UnzipUtility();
        try {
            unzipUtility.unzip(localFilePath, parentPath);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void Downloader(String fileName) {

        String user = "1234";
        String pass = "1234";
        String host = "1234";
        int portNum = 22;

        JSch jsch = new JSch();
        Session session;

        try {

            session = jsch.getSession(user,host,portNum);
            session.setConfig("StrictHostKeyChecking", "no");
            session.setPassword(pass);
            session.connect();

            Channel channel = session.openChannel("sftp");
            channel.connect();
            ChannelSftp sftpChannel = (ChannelSftp) channel;


            File localFile = File.createTempFile("1234",".zip");
            sftpChannel.get(fileName,localFile.getAbsolutePath());
            //sftpChannel.get(fileName);

            Log.d(fileName, " has been downloaded");

            sftpChannel.exit();
            session.disconnect();
            localFilePath = localFile.getAbsolutePath();
            parentPath = localFile.getParent();
        } catch (JSchException | IOException | SftpException e) {
            e.printStackTrace();
        }
    }


}

出于安全原因,我编辑了数据字段。

【问题讨论】:

  • 你在哪里得到 null ?
  • 发布错误日志
  • 能介绍一下主要课程吗?
  • 你说的不可能。你肯定传递了一些错误的东西。尝试调试。
  • @sasikumar 在调试过程中,我在解压缩方法定义中得到了空值。

标签: java android oop


【解决方案1】:

可以删减以下几行:

UnzipUtility unzipUtility = new UnzipUtility();
try {
    unzipUtility.unzip(localFilePath, parentPath);
} catch (IOException e) {
    e.printStackTrace();
}

SFTPActivity 类中的以下行下方粘贴:

Downloader(fileName); 

方法doInBackground。 实际上,doInBackground() 方法在与onCreate 方法运行所在的线程不同的线程中运行。您尝试在方法 Downloader(fileName) 完成其工作之前使用变量。这就是为什么您会在以下变量中看到空值的原因:localFilePathparentPath

【讨论】:

  • 非常感谢。这行得通! :) 谢谢你的解释。
  • 我很想投票,但我没有足够的声誉! :( 抱歉。还有其他方法吗?
【解决方案2】:

你的代码不起作用的原因是因为在运行这一行时:

unzipUtility.unzip(localFilePath, parentPath);

变量localFilePathparentPath尚未设置。

您可能会争辩说它们在方法Downloader 中设置的,该方法在unzip 行之前调用。不幸的是,这不是真的。在这种情况下,代码执行不是线性的,因为您使用的是AsyncTask。异步任务中的内容与其后面的行同时运行。

您的下载调用不会在调用unzipUtility.unzip 之前完成,因为与创建新的UnzipUtility 对象相比,下载需要大量时间。

这就是localFilePathparentPath 为空的原因。

解决此问题的一种方法是将解压缩逻辑也移到异步任务中:

new AsyncTask<Void, Void, List<String>>() {
    @Override
    protected List<String> doInBackground(Void... params) {
        try {
            Downloader(fileName);

            UnzipUtility unzipUtility = new UnzipUtility();
            unzipUtility.unzip(localFilePath, parentPath);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}.execute();

另一种方法是在AsyncTask 中也覆盖onPostExecute

new AsyncTask<Void, Void, List<String>>() {
     // doInBackground goes here...

     @Override
     protected void onPostExecute(Long result) {
         try {
            UnzipUtility unzipUtility = new UnzipUtility();
            unzipUtility.unzip(localFilePath, parentPath);
         } catch (Exception e) {
            e.printStackTrace();
         }
     }
}

【讨论】:

  • 好的。感谢您的详细解释。下次会牢记这些要点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-12
  • 1970-01-01
  • 1970-01-01
  • 2015-09-14
  • 2018-02-27
  • 1970-01-01
相关资源
最近更新 更多