【问题标题】:Positive value gets negative正值变为负值
【发布时间】:2017-08-21 00:14:21
【问题描述】:

抱歉,我不知道问题的标题应该是什么。谁能告诉我这怎么可能?

绿线还没有执行。

编辑:这里 tmp 和 size 肯定是正整数。

编辑:源代码:

public class MyDownloadService extends IntentService {
String urlD, name, sole, urlOfImage = "";
Context conte;
static int q = -1;
int progress = 0, nin, tmp = 0;
File file;
public static final String NOTIFICATION = "com.example.downloader2.ShowDownloadsActivity";
public static final String NOTIFICATION2 = "com.example.downloader2.ShowDownloadsActivity2";
AppGlobal apg;

public MyDownloadService(String name) {
    super("Downloading");
}

public MyDownloadService() {
    super("Downloading");
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    q = q + 1;
    return super.onStartCommand(intent, flags, startId);
}

@Override
public void onCreate() {
    super.onCreate();
    conte = this;
}

@Override
protected void onHandleIntent(Intent intent) {
    apg = (AppGlobal) getApplication();
    urlD = intent.getExtras().getString("url");
    name = intent.getExtras().getString("name");
    nin = intent.getExtras().getInt("nin");
    urlOfImage = intent.getExtras().getString("urlOfImage");
    int ret = intent.getExtras().getInt("retry");
    if (ret == 1) {
        Toast.makeText(conte,
                "Please wait... Your download will start soon",
                Toast.LENGTH_SHORT).show();
    }
    sole = name;
    try {
        int size = 0;
        final int TIMEOUT_CONNECTION = 15000;// 15sec
        final int TIMEOUT_SOCKET = 30000;// 30sec
        String imageURL = urlD;
        URL url = new URL(imageURL);
        long startTime = System.currentTimeMillis();
        Log.e("Note: ", "image download beginning: " + imageURL);
        // Open a connection to that URL.
        URLConnection ucon = url.openConnection();

        // this timeout affects how long it takes for the app to realize
        // there's a connection problem
        ucon.setReadTimeout(TIMEOUT_CONNECTION);
        ucon.setConnectTimeout(TIMEOUT_SOCKET);

        // Define InputStreams to read from the URLConnection.
        // uses 3KB download buffer
        InputStream is = ucon.getInputStream();
        size = ucon.getContentLength();
        BufferedInputStream inStream = new BufferedInputStream(is, 1024 * 5);
        File wallpaperDirectory = new File(
                Environment.getExternalStorageDirectory() + "/myFold");
        wallpaperDirectory.mkdirs();
        // sole = sole.replace("?", "_");
        // sole = sole.replace("|", "_");
        // sole = sole.replace("/", "_");
        // sole = sole.replace(":", "_");
        // sole = sole.replace("$", "_");
        file = new File(wallpaperDirectory + File.separator + sole);
        if (file.exists()) {
            file.delete();
        }

        file.createNewFile();
        apg.setInDownload(true);
        FileOutputStream outStream = new FileOutputStream(file);
        byte[] buff = new byte[5 * 1024];

        // Read bytes (and store them) until there is nothing more to
        // read(-1)
        int len;
        tmp = 0;
        while ((len = inStream.read(buff)) != -1) {
            if (apg.getCont()) {
                apg.setCont(false);
                stopSelf();
                Intent inten = new Intent();
                inten.putExtra("urlToDownload", urlD);
                inten.putExtra("timeout", 7);
                inten.putExtra("name", sole);
                inten.putExtra("progress", progress);
                inten.putExtra("nin", nin);
                inten.putExtra("url", urlD);
                inten.setAction("com.example.downloader2.BR");
                sendBroadcast(inten);
                Intent in2 = new Intent(NOTIFICATION);
                in2.putExtra("progress", progress);
                in2.putExtra("running", 0);
                in2.putExtra("name", sole);
                q--;
                sendBroadcast(in2);
                progress = 0;
                if (file.exists()) {
                    file.delete();
                }
                outStream.close();
                return;
            }
            tmp = tmp + len;
            progress = (tmp * 100) / size;
            if(progress<0)
                progress=-1*progress;
            outStream.write(buff, 0, len);
            publishP();
        }
        tmp = size;
        progress = 101;
        publishP();
        // clean up

        outStream.flush();
        outStream.close();
        inStream.close();
        Log.e("Note: ",
                "Download completed in "
                        + ((System.currentTimeMillis() - startTime) / 1000)
                        + " secs.");
    } catch (Exception e) {
        if (file.exists()) {
            file.delete();
        }
        apg.setInDownload(false);
        Intent inten = new Intent();
        inten.putExtra("urlToDownload", urlD);
        if (e.toString()
                .equals("java.io.IOException: open failed: EACCES (Permission denied)")) {
            inten.putExtra("timeout", 5);
        } else {
            inten.putExtra("timeout", 1);
        }
        inten.putExtra("name", sole);
        inten.putExtra("progress", progress);
        inten.putExtra("nin", nin);
        inten.putExtra("url", urlD);
        inten.setAction("com.example.downloader2.BR");
        sendBroadcast(inten);
        Intent in2 = new Intent(NOTIFICATION);
        in2.putExtra("progress", progress);
        in2.putExtra("running", 0);
        in2.putExtra("name", sole);
        q--;
        sendBroadcast(in2);
        progress = 0;
        Log.e("Error: ", "Error is:" + e.toString());
    }
}

protected void publishP() {
    try {
        Intent intent = new Intent();
        intent.putExtra("timeout", 0);
        intent.putExtra("progress", progress);
        intent.putExtra("nin", nin);
        intent.putExtra("name", sole);
        intent.setAction("com.example.downloader2.BR");
        sendBroadcast(intent);
        Intent in2 = new Intent(NOTIFICATION);
        if (progress > 100)
            q--;
        in2.putExtra("progress", progress);
        in2.putExtra("running", 1);
        in2.putExtra("name", sole);
        in2.putExtra("queue", q);
        sendBroadcast(in2);
    } catch (Exception e) {
        Log.e("Shit", e.toString());
    }
}

@Override
public boolean stopService(Intent name) {
    return super.stopService(name);
}
}

编辑:这 3 个快照是我在相同的调试器状态下拍摄的:

【问题讨论】:

  • 你到底想要什么?
  • 我正在使用此代码来检查进度是否为正。如果是负数,它必须变成正数。但是如果它已经是肯定的,我就不能进入 if 语句。
  • 请粘贴源代码。从快照中不清楚。你怎么确定是阳性?日志语句还是调试器?
  • 你的 tmp 和 size 是正数,所以进度不应该是负数。您不必检查进度。
  • @handrenliang 那怎么跳转到if语句呢?

标签: android


【解决方案1】:

这称为溢出。当一个数字太大时,它就不能正确表示并变为负数。搜索术语“溢出”以获取详细信息。

你可以试试(float)tmp / size * 100,基本原理是在计算过程中确保数字不超过100。

请注意浮点转换是必要的,因为整数除法总是会给你一个整数。在您的情况下,如果您不进行强制转换,您将始终得到 0。

【讨论】:

  • 听起来不错的答案。让我试试:)
  • 和 tmp 和 size 应该很长
  • @Bear 先生,看来工作正常,谢谢。但我还想知道一件事。我发布的第一张图片中的东西怎么可能??
  • 我不确定,我认为您的断点实际上在运行该行后(否定后)打印了进度的值?
  • 或者在后台运行异步任务时,您不确定您正在读取的值是否真的是调试器行中的值。
【解决方案2】:

你为什么不简单地使用

progress = abs((tmp * 100) / size);

这样你的进步总是积极的并摆脱 if 语句?

【讨论】:

  • 是的,但我想知道它是如何发生的。
【解决方案3】:

int 可以容纳的最大值为2147483647,您可以从doc here 中查看它。当您将 temp 乘以 100 时,它会溢出并给出错误的值。除以大小后只需乘以 100。

【讨论】: