【问题标题】:How to use Async task with progressbar from a different activity in android如何在android中的不同活动中使用带有进度条的异步任务
【发布时间】:2016-03-30 09:45:18
【问题描述】:

我在这个项目中使用了 elasticView 进度条库。当我直接在单个ActivityAsyncTask 中使用它时,它工作正常,但是当我创建新的Java 类以从MainActivity 下载和访问时。它显示类未找到异常。这是我的完整代码和错误日志。


主活动


public class MainActivity extends AppCompatActivity {
    Button b1;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        b1=(Button)findViewById(R.id.button);
        b1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                download d=new download();
                d.startdownload();
            }
        });
    }

下载.java


import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Toast;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import it.michelelacorte.elasticprogressbar.ElasticDownloadView;

public class download extends AppCompatActivity {
    ElasticDownloadView mElasticDownloadView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.elastic);

        mElasticDownloadView = (ElasticDownloadView) findViewById(R.id.elastic_download_view);
        mElasticDownloadView.setVisibility(View.VISIBLE);

        startdownload();
    }

    public void startdownload() {

        final DownloadTask downloadTask = new DownloadTask(download.this);
        mElasticDownloadView.setVisibility(View.GONE);
        downloadTask.execute("http://farm1.static.flickr.com/114/298125983_0e4bf66782_b.jpg");
    }

    private class DownloadTask extends AsyncTask<String, Integer, String> {
        private Context context;

        public DownloadTask(Context context) {
            this.context = context;
        }

        @Override
        protected String doInBackground(String... sUrl) {


            InputStream input = null;
            OutputStream output = null;
            HttpURLConnection connection = null;
            try {
                URL url = new URL(sUrl[0]);
                connection = (HttpURLConnection) url.openConnection();
                connection.connect();
                if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
                    return "Server returned HTTP " + connection.getResponseCode()
                            + " " + connection.getResponseMessage();
                }

                int fileLength = connection.getContentLength();
                input = connection.getInputStream();
                output = new FileOutputStream("/sdcard/some_photo_from_gdansk_poland.jpg");

                byte data[] = new byte[4096];
                long total = 0;
                int count;
                while ((count = input.read(data)) != -1) {

                    if (isCancelled()) {
                        input.close();
                        return null;
                    }
                    total += count;

                    if (fileLength > 0) {
                        int status = ((int) (total * 100 / fileLength));
                        publishProgress(status);
                    }
                    output.write(data, 0, count);
                }
            } catch (Exception e) {
                return e.toString();
            } finally {
                try {
                    if (output != null)
                        output.close();
                    if (input != null)
                        input.close();
                } catch (IOException ignored) {
                }

                if (connection != null)
                    connection.disconnect();
            }
            return null;

        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            mElasticDownloadView.startIntro();
        }

        @Override
        protected void onProgressUpdate(Integer... progress) {
            super.onProgressUpdate(progress);
            mElasticDownloadView.setProgress(10);
        }

        @Override
        protected void onPostExecute(String result) {
            mElasticDownloadView.success();
            if (result != null)
                Toast.makeText(context, "Download error: " + result, Toast.LENGTH_LONG).show();
        }
    }
}

activity_main.xml


 <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context="net.logicalsteps.download_notif.MainActivity">

        <include layout="@layout/elastic"/>

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="start download"
            android:id="@+id/button"
            android:layout_alignParentTop="true"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="31dp" />
    </RelativeLayout>

elastic.xml


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="wrap_content"
    android:layout_height="100dp"
    android:layout_alignParentBottom="true"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true">

    <it.michelelacorte.elasticprogressbar.ElasticDownloadView
        android:id="@+id/elastic_download_view"
        android:layout_width="match_parent"
        android:layout_height="90dp"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_marginBottom="27dp" />



</RelativeLayout>

错误日志:


E/AndroidRuntime: FATAL EXCEPTION: main 
Process: net.logicalsteps.download_notif, PID: 23132  
java.lang.NullPointerException: Attempt to invoke virtual method 'void it.michelelacorte.elasticprogressbar.ElasticDownloadView.setVisibility(int)' on a null object referenc
        at net.logicalsteps.download_notif.download.startdownload(download.java:41)
        at net.logicalsteps.download_notif.MainActivity$1.onClick(MainActivity.java:39)
        at android.view.View.performClick(View.java:5162)
        at android.view.View$PerformClick.run(View.java:20873)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)                                      at android.os.Looper.loop(Looper.java:145)                                         at android.app.ActivityThread.main(ActivityThread.java:5835)                                         at java.lang.reflect.Method.invoke(Native Method)                                         at java.lang.reflect.Method.invoke(Method.java:372)                                              at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1388                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1183)

【问题讨论】:

  • 首先启动活动下载,以便可以初始化视图,然后使用视图的可见性。或者不要使用另一个活动下载,只需制作 AsynTask 扩展类并更改 mainActivity 中的视图。

标签: android exception android-asynctask download


【解决方案1】:

你需要从另一个Activity开始一个Intent,否则,你的类将被初始化,但Activity不会启动它的生命周期(onCreate方法等不会被调用) :

    b1.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent downloadIntent = new Intent(v.getContext(), download.class);
            startActivity(downloadIntent);
        }
    });

如果您不想打开一个新的Activity,您可以将您的AsyncTask 移动到您的MainActivity,当它下载时,您可以使用您的ProgressBar 显示一个自定义AlertDialog。您可以在此here 上找到更多信息。

【讨论】:

    【解决方案2】:

    你只需要看看这里

     download d=new download();
     d.startdownload();
    

    您调用了 startdownload() 方法,但直到那时 onCreatedownload Activity 未被调用,因此无法初始化 mElasticDownloadView。因此,也可以在 startdownload 方法中或任何您感觉舒适的地方初始化它,或者在 onClick() 方法中启动 Activity download

    【讨论】:

      【解决方案3】:

      错误原因

      发生这种情况的原因是,当系统启动download 活动时,它会执行设置mElasticDownloadView = ...download.onCreate。但是当你在onClick 中创建它时,你不会调用onCreate 所以mElasticDownloadView 不会被初始化。

      使用活动

      现在在onClick 中创建download Activity 的实例:

      download d=new download();
      d.startdownload();
      

      这不是创建活动的常用方式。如果您这样做,活动将不会从布局 XML 文件中扩展其所有 UI,因此也没有进度条。如果你想显示活动,你应该使用:

      Intent intent = new Intent(MainActivity.this, download.class);
      startActivity(intent);
      

      现在,如果你想向 Activity 传递消息,你可以通过 Intent 传递它:

      intent.putExtra(EXTRA_MESSAGE, message);
      

      然后在download.onStart你可以检索到这条消息getIntent().getStringExtra(...)

      但是,无论如何,在您的download.onCreate 中您调用startdownload,因此您不需要进行消息传递。

      在此处了解更多信息:https://developer.android.com/training/basics/firstapp/starting-activity.html

      【讨论】:

      • :感谢您提供的宝贵信息。我理解错误。
      • 你能给我一个不使用意图来处理这个问题的方法吗?我的意思是,我需要屏幕上的这个进度条,直到下载完成就像一个浮动项目。即使我们搬出去它也不应该消失到另一个页面。
      • 您可以从多个视图(其中一个是进度条)组成一个活动。如果没有,你应该看看 Fragments。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-14
      • 2014-11-16
      • 1970-01-01
      • 2017-11-26
      • 1970-01-01
      相关资源
      最近更新 更多