Android Parcelable(传递Bitmap)应用

先不废话先上代码吧! 我们就不讲intent的传递方式了因为这个很常见
Parcelable

public class NewsBean implements Parcelable {

    public String name;

    public int age;

    public String profession;

    public byte[] bytesFromBitmap;

    public NewsBean(Parcel in) {
        name = in.readString();
        age = in.readInt();
        profession = in.readString();
        bytesFromBitmap = in.createByteArray();
    }

    public static final Creator<NewsBean> CREATOR = new Creator<NewsBean>() {
        @Override
        public NewsBean createFromParcel(Parcel in) {
            return new NewsBean(in);
        }

        @Override
        public NewsBean[] newArray(int size) {
            return new NewsBean[size];
        }
    };

    public NewsBean(String benZeph, int i, String s, byte[] bytesFromBitmap) {
        this.name = benZeph;
        this.age = i;
        this.profession = s;
        this.bytesFromBitmap=bytesFromBitmap;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeInt(age);
        dest.writeString(profession);
        dest.writeByteArray(bytesFromBitmap);
    }
}

注意⚠️因为Parcelable里面没有传递bitmap的方法所以这边先将数据类变为ByteArray,后续会转换过来设置就行了

//bitmap转byte
    private byte[] getBytesFromBitmap(Bitmap bitmap) {
        ByteArrayOutputStream outputStream = 
            new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 0, outputStream);
        return outputStream.toByteArray();
    }

    //byte转bitmap
    private Bitmap getBitmapFromArrayBytes(byte[] bytes){
        return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
    }

使用 接下来这两个类是用于将数据透传递到自定义view(为了自定义view添加任何网络请求)
请添加图片描述
TargetApi类

/** Indicates that Lint should treat this type as targeting a given API level, no matter what the
 project target is. */
@Target({TYPE, METHOD, CONSTRUCTOR, FIELD})
@Retention(RetentionPolicy.CLASS)
public @interface TargetApi {
    /**
     * This sets the target api level for the type..
     */
    int value();
}

RemotableViewMethod类

/**
 * @hide
 * This annotation indicates that a method on a subclass of View
 * is alllowed to be used with the {@link android.widget.RemoteViews} mechanism.
 */
@TargetApi(30)
@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface RemotableViewMethod {
    /**
     * @return Method name which can be called on a background thread. It should have the
     * same arguments as the original method and should return a {@link Runnable} (or null)
     * which will be called on the UI thread.
     */
    String asyncImpl() default "";
}

//数据管理类

public class MyDemoDataManager {
    private static final long FLAG_REQUEST_TIME_OUT = 5 * 1000;//flag icon 超时 5s
    private String url = "https://wx1.sinaimg.cn/large/006L5ZD9ly8gt6y744rraj30dw0dwmxw.jpg";

    private static int FLAG_ICON_SIZE;

    static {
        FLAG_ICON_SIZE = 13;
    }

    private volatile static MyDemoDataManager sInstance;

    public Context mContext;

    private ArrayList<NewsBean> mNews = new ArrayList<NewsBean>();

    public static MyDemoDataManager getInstance(Context context) {
        if (sInstance == null) {
            synchronized (MyDemoDataManager.class) {
                if (sInstance == null) {
                    sInstance = new MyDemoDataManager(context);
                }
            }
        }
        return sInstance;
    }

    private MyDemoDataManager(Context context) {
        if (context.getApplicationContext() != null) {
            mContext = context.getApplicationContext();
        } else {
            mContext = context;
        }
        init();
    }

    private void init() {
        Bitmap bitmap = loadImageSync(url, 30, 30);
        byte[] bytesFromBitmap = getBytesFromBitmap(bitmap);
        NewsBean benParcelable = new NewsBean("BenZeph", 23, "1111",bytesFromBitmap);
        NewsBean benParcelable1 = new NewsBean("BenZeph", 23, "1111",bytesFromBitmap);
        NewsBean benParcelable2 = new NewsBean("BenZeph", 23, "1111",bytesFromBitmap);
        mNews.add(benParcelable);
        mNews.add(benParcelable1);
        mNews.add(benParcelable2);

    }
    //bitmap转byte
    private byte[] getBytesFromBitmap (Bitmap bitmap){
        ByteArrayOutputStream outputStream =
                new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 0, outputStream);
        return outputStream.toByteArray();
    }
    
    //使用blockingQueue和异步线程 实现带有超时的 同步图片请求(添加依赖这个方法就可以用)
    public static Bitmap loadImageSync(final String url, final int width, final int height) {
        final LinkedBlockingDeque<Bitmap[]> blockingDeque = new LinkedBlockingDeque<Bitmap[]>();
        ConcurrentManager.getInsance().execute(new Runnable() {
            @Override
            public void run() {
                try {
                    Bitmap bm = ImageLoader.getInstance().loadImageSync(url, new ImageSize(width, height));
                    blockingDeque.offer(new Bitmap[]{bm});
                } catch (Throwable t) {
                    t.printStackTrace();
                    blockingDeque.offer(new Bitmap[]{null});
                    Log.e("HotSearchWidgetPresenter loadImageSync:t", t + "");

                }
            }
        });
        try {
            Bitmap[] poll = blockingDeque.poll(FLAG_REQUEST_TIME_OUT, TimeUnit.MILLISECONDS);
            return poll == null ? null : poll[0];
        } catch (InterruptedException e) {
            e.printStackTrace();
            Log.e("HotSearchWidgetPresenter loadImageSync:", e + "");
        }
        return null;
    }

    public ArrayList<NewsBean> getNewsData() {
        return mNews;
    }

数据发送

 void updateAppWidget(Context context, final AppWidgetManager appWidgetManager, final int appWidgetId) {
        // Construct the RemoteViews object
        final RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.standard_app_widget);
        final Bundle bundle = new Bundle();
         bundle.setClassLoader(bundle.getClass().getClassLoader());
         ArrayList<NewsBean> newsData = MyDemoDataManager.getInstance(context).getNewsData();
         bundle.putParcelableArrayList("data", newsData);
         views.setBundle(R.id.my_rootview,"updateMyData",bundle);
         Log.d("tjk4","updateAppWidget appWidgetId = "+appWidgetId);
         // Instruct the widget manager to update the widget
         appWidgetManager.updateAppWidget(appWidgetId, views);
    }

数据接收

   @RemotableViewMethod
    public void updateMyData(Bundle bundle) {
        Log.d(TAG, "updateMyDatabundle.getClass()" + getClass().getClassLoader());
        bundle.setClassLoader(getClass().getClassLoader());
        ArrayList<NewsBean> newsDatas = bundle.getParcelableArrayList("data");
        Log.d(TAG, "updateMyData newsDatas.size=" + newsDatas.size());
        if (newsDatas != null) {
            mNewsViewPager.updateNews(newsDatas);
        }
    }

注意⚠️ bundle.setClassLoader(getClass().getClassLoader());这行代码一定要加不然就会报错
Class not found when unmarshalling,可能是获取不到对应的classLoader吧
注意⚠️bundle.getParcelableArrayList这个get类型一定要与传递的类型一致不然无法传递数据
然后到 mNewsViewPager.updateNews(newsDatas);我就不往后继续发了这个时候数据已经过来了后面就是项目代码了,大家可以避坑然后根据需求开发!
这样Parcelable的数据传递就完成✅了!

时间原因后续更新Serializable等!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王鑫林呀!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值