java - 加载通知图像的最佳方式?

标签 java android push-notification

关闭。这个问题需要更多 focused .它目前不接受答案。












想改进这个问题?更新问题,使其仅关注一个问题 editing this post .

4年前关闭。




Improve this question




加载通知图像的最佳方式是什么?

这是我目前的方式:如您所见,图像同步加载,因此通知可能会延迟。这是一个不好的方法。

public Bitmap getBitmapFromURL(String strURL) {
    try {
        URL url = new URL(strURL);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setDoInput(true);
        connection.connect();
        InputStream input = connection.getInputStream();
        Bitmap myBitmap = BitmapFactory.decodeStream(input);
        return myBitmap;
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    }
}

Bitmap bitmap = getBitmapFromURL("https://graph.facebook.com/YOUR_USER_ID/picture?type=large");

// CONSTRUCT THE NOTIFICATION DETAILS
builder.setAutoCancel(true);
builder.setSmallIcon(R.drawable.ic_launcher);
builder.setContentTitle("Some Title");
builder.setContentText("Some Content Text");
builder.setLargeIcon(bitmap);
builder.setContentIntent(pendingIntent);

我真的需要一个答案来继续我的项目。

最佳答案

您应该首先通知没有图像或占位符的通知,然后使用 AsyncTask 加载位图,或使用 Picasso 和 Target 回调。

将您用于第一次通知的构建器提供给您的任务,当加载位图时,将其添加到构建器中,然后重新通知您的通知。

如果在完整的图像加载之前内容已更改的风险,请存储一个变量来标识您要显示的当前内容,您可以在重新通知之前检查该变量。

您可以按照 google UniversalMusicPlayer 提供的 MediaNotificationManager 示例进行操作项目。

在你的情况下:

// CONSTRUCT THE NOTIFICATION DETAILS
builder.setAutoCancel(true);
builder.setSmallIcon(R.drawable.ic_launcher);
builder.setContentTitle("Some Title");
builder.setContentText("Some Content Text");
//builder.setLargeIcon(bitmap); // replace this line with place holder drawable from resources
builder.setContentIntent(pendingIntent);

manager.notify(NOTIFICATION_ID, builder.build());

currentLoadImageTask = new LoadImageTask(manager, builder);
currentLoadImageTask.execute("https://graph.facebook.com/YOUR_USER_ID/picture?type=large");

// ...

static class LoadImageTask extends AsyncTask<String, Void, Bitmap> {

    final NotificationManager manager;
    final NotificationCompat.Builder builder;

    public LoadImageTask(final NotificationManager manager, final NotificationCompat.Builder builder) {
        this.manager = manager;
        this.builder = builder;
    }

    @Override
    protected Bitmap doInBackground(final String... strings) {
        if (strings == null || strings.length == 0) {
            return null;
        }
        try {
            final URL url = new URL(strings[0]);
            final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setDoInput(true);
            connection.connect();
            final InputStream input = connection.getInputStream();
            return BitmapFactory.decodeStream(input);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    protected void onPostExecute(final Bitmap bitmap) {
        if (bitmap == null || manager == null || builder == null) {
            return;
        }
        builder.setLargeIcon(bitmap);
        manager.notify(NOTIFICATION_ID, builder.build());
    }
}

毕加索:
// CONSTRUCT THE NOTIFICATION DETAILS
builder.setAutoCancel(true);
builder.setSmallIcon(R.drawable.ic_launcher);
builder.setContentTitle("Some Title");
builder.setContentText("Some Content Text");
//builder.setLargeIcon(bitmap); // replace this line with place holder drawable from resources
builder.setContentIntent(pendingIntent);

manager.notify(NOTIFICATION_ID, builder.build());

// ...

Picasso.with(context)
    .load("https://graph.facebook.com/YOUR_USER_ID/picture?type=large")
    .resize(250, 250)
    .into(new Target() {
        @Override
        public void onBitmapLoaded(final Bitmap bitmap, final Picasso.LoadedFrom from) {
            builder.setLargeIcon(bitmap);
            manager.notify(NOTIFICATION_ID, builder.build());
        }

        @Override
        public void onBitmapFailed(final Drawable errorDrawable) {
             // Do nothing
        }

        @Override
        public void onPrepareLoad(final Drawable placeHolderDrawable) {
             // Do nothing
        }
    });

如果不在 UiThread 中,您可以创建一个 Runnable 并在 Looper 中执行它
 final Handler uiHandler = new Handler(Looper.getMainLooper());
 uiHandler.post(new Runnable() {
      @Override
      public void run() {
           // Call from here
      }
 });

毕加索要好得多,仅仅是因为使用了缓存。

我强烈建议您调整在通知中设置的每个位图的大小,因为如果您不这样做,它很容易引发 OutOfMemoryException。

关于java - 加载通知图像的最佳方式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45721090/

相关文章:

android - 应用混淆器时 Gson 崩溃

android - Azure -> Node.js 中的 Easy api -> 如何发送 Android 推送通知?

android - Android GCM 的问题

android - 无法合并dex-Android Studio 3.0.1

java - 根据 Spark 中的等级分离数据集

java - 变量启动中的 NullPointerException

java - 评估执行相同功能的不同条件的通用方法

android - 找不到Gradle DSL方法: 'registerResGeneratingTask()'

android - Android中单个设备的多个APP ID的Under Urban Airship

Java 将对象传递给方法