先不废话先上代码吧! 我们就不讲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等!
|