【问题标题】:AsyncTask.get() in Activity.onCreate makes it take too much time to load and sometimes it crashes [closed]Activity.onCreate 中的 AsyncTask.get() 导致加载时间过长,有时会崩溃 [关闭]
【发布时间】:2021-10-19 18:41:08
【问题描述】:

当我开始这个活动时,加载时间太长,有时我的应用程序会崩溃。我想知道我是否可以做任何事情,以便在主要活动在前一个活动中完全加载或类似的事情之前,活动不会开始,因此我的活动将加载而不会出现问题或崩溃。

AdvertisingActivity.java

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.vectordrawable.graphics.drawable.Animatable2Compat;

import android.app.ProgressDialog;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Handler;
import android.view.View;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.load.resource.gif.GifDrawable;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.Target;

import java.util.concurrent.ExecutionException;

public class AdvertisingActivity extends AppCompatActivity {
    ImageView imageView;
    ImageView imageButton;
    String ImageClick = "";
    String ImageLink = "";
    private TextView Countdowner;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.advertising);
        getSupportActionBar().hide();
        imageView = findViewById(R.id.Advertisings);
        imageButton = findViewById(R.id.closebuttons);
        imageButton.setVisibility(View.GONE);
        Countdowner = findViewById(R.id.Countdowns);
        final ParseJson parsejson = new ParseJson();
        try {
            parsejson.execute().get();

        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        ImageLink = parsejson.getHouseAdsImage();
        ImageClick = parsejson.getHouseAdsClick();
        boolean ifGif = parsejson.getGIF();


        imageButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                finish();
            }
        });

        imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(parsejson.getHouseAdsClick()));
                AdvertisingActivity.this.startActivity(browserIntent);
            }
        });


        if (ifGif == true) {
            Glide.with(this).asGif().load(parsejson.getHouseAdsImage()).listener(new RequestListener<GifDrawable>() {
                @Override
                public boolean onLoadFailed(@Nullable @org.jetbrains.annotations.Nullable GlideException e, Object model, Target<GifDrawable> target, boolean isFirstResource) {
                    finish();
                    Toast.makeText(AdvertisingActivity.this, "Failed to load", Toast.LENGTH_SHORT).show();
                    return false;
                }

                @Override
                public boolean onResourceReady(GifDrawable resource, Object model, Target<GifDrawable> target, DataSource dataSource, boolean isFirstResource) {
                    resource.setLoopCount(1);
                    resource.registerAnimationCallback(new Animatable2Compat.AnimationCallback() {
                        @Override
                        public void onAnimationEnd(Drawable drawable) {
                            Glide.with(AdvertisingActivity.this).load(parsejson.getAfterGif()).into(imageView);
                            Toast.makeText(AdvertisingActivity.this, "GIF stopped", Toast.LENGTH_SHORT).show();
                        }
                    });
                    new CountDownTimer(13000, 1000) {

                        public void onTick(long millisUntilFinished) {
                            Countdowner.setText("You can close ad after: " + millisUntilFinished / 1000);
                        }

                        public void onFinish() {
                            imageButton.setVisibility(View.VISIBLE);
                            Countdowner.setVisibility(View.GONE);
                        }
                    }.start();
                    Toast.makeText(AdvertisingActivity.this, "Success to load", Toast.LENGTH_SHORT).show();

                    return false;
                }
            }).into(imageView);

        } else {
            Glide.with(AdvertisingActivity.this).load(parsejson.getAfterGif()).into(imageView);

        }
    }
}

【问题讨论】:

  • 当它崩溃时,日志中有什么?有例外吗?
  • @KevinHooke 从我的主机加载数据需要太多时间
  • AsyncTask 已被弃用几年。请考虑使用其他东西:普通线程、来自ExecutorsExecutor、RxJava、Kotlin 协程等。
  • 这是为了上课吗?如果不是,那么您使用的任何教程都可能已经过时了。 Android 现在通常在 Kotlin 中完成
  • @Novaterata 是的一类。我仍在使用 Java。

标签: java android android-asynctask


【解决方案1】:

您的问题是您正在主线程上同步等待 AsyncTask 完成:

parsejson.execute().get();

您基本上不应该在主线程上调用AsyncTask.get():它会阻塞线程直到它完成,这违背了 AsyncTask 的要点,即阻塞主线程。

相反,您应该在AsyncTask.onPostExecute 中等待您做的任何事情。

【讨论】:

  • 我明白了,非常感谢。
  • 我要把 doInBackground 中写的内容移到 onPostExecute 吗?
  • @JosephLanga 不,onPostExecute 应该是您当前在 UI 线程上执行的操作,这取决于 doInBackground 中的内容是否已完成。
  • @JosephLanga 如果不清楚,“异步/异步”意味着代码将在“后台”运行,通常使用单独的处理器线程;但是,有时会在同一线程上使用交错。因此,有一个阶段是您提交任务,然后是您等待它完成的阶段(如果您需要结果)(可选,您可以让它运行而忽略结果,即即发即弃)。
  • @Novaterata 我明白了。太感谢了。我将 ProgressDialog 添加到我的代码中,因此当用户打开活动时,进度对话框会出现,直到异步完成,然后进度对话框就会消失。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-12
相关资源
最近更新 更多