Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/194.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android sendBroadcast仅在while循环中发送一次_Android_Multithreading_While Loop_Broadcastreceiver_Broadcast - Fatal编程技术网

Android sendBroadcast仅在while循环中发送一次

Android sendBroadcast仅在while循环中发送一次,android,multithreading,while-loop,broadcastreceiver,broadcast,Android,Multithreading,While Loop,Broadcastreceiver,Broadcast,我正在下载一个服务中启动的线程中的图像。一切正常,但我想在MainActivity/UI线程内的进度栏中显示进度。我想通过广播信息做到这一点。正如您在下面的代码中看到的,我在启动线程的服务的while循环中调用sendBroadcast方法。它可以工作,但在最后一个循环中只有一次,当图像完全下载时。所以Progressbar最终显示100%。我的问题是:为什么最后才调用它,我能做些什么 编辑:我必须使用广播消息。这是一项大学运动 线程中的相关代码: URL url = null;

我正在下载一个服务中启动的线程中的图像。一切正常,但我想在MainActivity/UI线程内的进度栏中显示进度。我想通过广播信息做到这一点。正如您在下面的代码中看到的,我在启动线程的服务的while循环中调用sendBroadcast方法。它可以工作,但在最后一个循环中只有一次,当图像完全下载时。所以Progressbar最终显示100%。我的问题是:为什么最后才调用它,我能做些什么

编辑:我必须使用广播消息。这是一项大学运动

线程中的相关代码:

    URL url = null;
    int fileSize = 0;


    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    InputStream is = null;
    try {
        url = new URL(src);
        URLConnection connection = url.openConnection();
        connection.connect();
        fileSize = connection.getContentLength();
    } catch (MalformedURLException e) {
        e.printStackTrace();
        Log.d("LOG", "URL not found");
    } catch (IOException e) {
        e.printStackTrace();
        Log.d("LOG","Couldnt get Size of the file from this connection - No File found");
    }
    try {
        is = url.openStream ();
        byte[] byteChunk = new byte[1024];
        Intent progressIntent = new Intent();
        progressIntent.setAction(Constants.ACTION.UPDATE_PROGRESSBAR);
        int n;
        int currentSize = 0;
        while ( (n = is.read(byteChunk)) > 0 ) {
            currentSize = currentSize + n;
            baos.write(byteChunk, 0, n);
            progressIntent.putExtra("imgName", imgName);
            progressIntent.putExtra("progressValue", (int) ((currentSize/fileSize)*100));
            runningService.sendBroadcast(progressIntent);
        }
我的接收人:

public class Receiver extends BroadcastReceiver{

MainActivity main;

public Receiver(){};

public Receiver(MainActivity main){
    this.main = main;
}

@Override
public void onReceive(Context context, Intent intent) {
    if(intent.getAction().equals(Constants.ACTION.TRANSFER_BYTEARRAY)){
        byte[] byteArray = intent.getByteArrayExtra("imgBA");
        String imgName = intent.getStringExtra("imgName");
        main.setDownloadedImg(byteArray,imgName);
    } else if (intent.getAction().equals(Constants.ACTION.UPDATE_PROGRESSBAR)) {
        String imgName = intent.getStringExtra("imgName");
        int progressValue = intent.getIntExtra("progressValue",0);
        main.updateProgressBar(imgName, progressValue);
    }
}

}我建议不要发送那么多广播信息。如果您可以使用observer模式进行此操作,则会更加专业。很好地解释了如何使用它

基本上有3个步骤:

  • 您必须创建一个界面,其中包含一种更新进度条的方法:

    public interface ProgressChangeListener{
        void onProgressChanged(int percent);
    }
    
    如果您的MainActivity处理进度条,那么接口应该由MainActivity实现

  • 当您实例化下载图像的线程时,必须传递一个
    ProgressChangeListener
    type对象,该对象基本上是您的MainActivity,它实现了此侦听器

  • 最后,当进度值更改时,只需在线程中调用该对象的
    onProgressChanged
    方法


  • 此解决方案比广播消息更有效,而且更加优雅。

    我建议不要发送太多广播消息。如果您可以使用observer模式进行此操作,则会更加专业。很好地解释了如何使用它

    基本上有3个步骤:

  • 您必须创建一个界面,其中包含一种更新进度条的方法:

    public interface ProgressChangeListener{
        void onProgressChanged(int percent);
    }
    
    如果您的MainActivity处理进度条,那么接口应该由MainActivity实现

  • 当您实例化下载图像的线程时,必须传递一个
    ProgressChangeListener
    type对象,该对象基本上是您的MainActivity,它实现了此侦听器

  • 最后,当进度值更改时,只需在线程中调用该对象的
    onProgressChanged
    方法


  • 此解决方案将比广播消息更有效,而且更加优雅。

    我知道会发生什么,但只是作为一个快速解决方案:如果你在循环中实例化你的意图,它会有帮助吗?没有-没有帮助。刚刚测试过:/Ok。因此,可能发生的情况是,您在下载的同一线程上处理进度,因此您的更新不能保证在呈现UI的线程上看到。使用
    Activity.runOnUIThread
    查找需要更新UI内容的内容。您确定吗?在我的主要活动中,我启动了一个服务,它启动线程来下载图片。线程正在发送广播消息。接收器已在UI线程上注册。。。所以我在UI线程中处理进度,不是吗?如果真的是这样,它仍然不起作用,那么它可能是一些计算中的错误。我知道会发生什么,但只是作为一个快速修复:如果你在循环中实例化你的意图,它会有帮助吗?没有-没有帮助。刚刚测试过:/Ok。因此,可能发生的情况是,您在下载的同一线程上处理进度,因此您的更新不能保证在呈现UI的线程上看到。使用
    Activity.runOnUIThread
    查找需要更新UI内容的内容。您确定吗?在我的主要活动中,我启动了一个服务,它启动线程来下载图片。线程正在发送广播消息。接收器已在UI线程上注册。。。所以我在UI线程中处理进度,不是吗?如果真是这样,它仍然不工作,那么它可能是一些计算中的错误。谢谢你的回答。这是一个大学练习,我必须使用广播信息。如果我不需要的话,我想我会使用异步任务。我会把这个添加到我的问题中。@L.Rex,我敢肯定,您实际上必须使用AsyncTask。如果在呈现UI的同一线程上更新了进度,UI将在最后一次更新之前不会显示任何进度,这看起来与您现在的大致相同。谢谢您的回答。这是一个大学练习,我必须使用广播信息。如果我不需要的话,我想我会使用异步任务。我会把这个添加到我的问题中。@L.Rex,我敢肯定,您实际上必须使用AsyncTask。如果在呈现UI的同一个线程上更新了进度,则UI将在最后一次更新之前不会显示任何进度,而最后一次更新看起来与您现在的大致相同。