我有一个类,它用所有必需的读写方法实现Parcelable接口。这些是我的可打包对象的重要方法...
...
public News() {
// Default constructor...
}
@SuppressWarnings("unchecked")
private News(Parcel in) {
this.feedId = in.readLong();
this.ownerId = in.readLong();
this.author = in.readParcelable(User.class.getClassLoader());
this.ownerUserName = in.readString();
this.title = in.readString();
this.content = in.readString();
this.image = in.readParcelable(NewsImage.class.getClassLoader());
this.videoUrl = in.readString();
this.date = in.readString();
this.tags = in.readArrayList(Hashtag.class.getClassLoader());
this.ownerNewspaperName = in.readString();
this.view = in.readString();
this.applaud = in.readString();
this.comment = in.readString();
this.announce = in.readString();
this.isApplauded = in.readByte() == 1;
this.isCommented = in.readByte() == 1;
this.isAnnounced = in.readByte() == 1;
this.isViewed = in.readByte() == 1;
this.isHidden = in.readByte() == 1;
this.isReported = in.readByte() == 1;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeLong(this.feedId);
dest.writeLong(this.ownerId);
dest.writeParcelable(this.author, flags);
dest.writeString(this.ownerUserName);
dest.writeString(this.title);
dest.writeString(this.content);
dest.writeParcelable(this.image, flags);
dest.writeString(this.videoUrl);
dest.writeString(this.date);
dest.writeList(this.tags);
dest.writeString(this.ownerNewspaperName);
dest.writeString(this.view);
dest.writeString(this.applaud);
dest.writeString(this.comment);
dest.writeString(this.announce);
dest.writeByte((byte) (this.isApplauded ? 1 : 0));
dest.writeByte((byte) (this.isCommented ? 1 : 0));
dest.writeByte((byte) (this.isAnnounced ? 1 : 0));
dest.writeByte((byte) (this.isViewed ? 1 : 0));
dest.writeByte((byte) (this.isHidden ? 1 : 0));
dest.writeByte((byte) (this.isReported ? 1 : 0));
}
public static final Creator<News> CREATOR = new Creator<News>() {
@Override
public News createFromParcel(Parcel source) {
return new News(source);
}
@Override
public News[] newArray(int size) {
return new News[size];
}
};
...
我的活动包含listview,而arrayadapter包含我的parcelable对象的arraylist。当点击列表项时,我将特定的可解析对象传递给DetailActivity,我可以毫无问题地读取可解析对象...直到现在一切都是完美的…大问题从这里开始..当我更改该对象的任何属性(写入)时,我实际上只是更改了克隆,而不是先前活动列表视图中保留的原始对象。我认为出现这个问题的原因是,Parcelable.Creator从parcel返回一个新对象,而不是god对象引用。
public class NewsDetailActivity extends Activity {
//private static final String TAG = "NewsDetailActivity";
public static final String KEY_NEWS = "news";
public static final String KEY_IS_WILLING_TO_COMMENT = "is_willing_to_comment";
private News news;
private float containerWidth;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_news_detail);
final ActionBarBuilder builder = new ActionBarBuilder(getActionBar());
builder.initializeSupportiveProperties();
final String screenName = getResources().getString(R.string.android) + "/" + getTitle();
final Tracker tracker = ((PapiroomApplication)getApplication()).getTracker(TrackerName.APP_TRACKER);
tracker.setScreenName(screenName);
tracker.send(new HitBuilders.AppViewBuilder().build());
news = getIntent().getParcelableExtra(KEY_NEWS);
final boolean isWillingToComment = getIntent().getBooleanExtra(KEY_IS_WILLING_TO_COMMENT, false);
containerWidth = this.getResources().getDisplayMetrics().widthPixels - 20;
// Layout initialization
final ScrollView scrollView = (ScrollView) findViewById(R.id.scrollView1);
final RoundedImageView imgNewsUser = (RoundedImageView) findViewById(R.id.imgNewsDetailUser);
final PapiroomTextView txtViewCount = (PapiroomTextView) findViewById(R.id.txtNewsView);
final PapiroomTextView txtNewspaperName = (PapiroomTextView) findViewById(R.id.txtNewsDetailNewspaperName);
final PapiroomTextView txtNewsUsername = (PapiroomTextView) findViewById(R.id.txtNewsDetailUsername);
final PapiroomTextView txtNewsDate = (PapiroomTextView) findViewById(R.id.txtNewsDetailDate);
final PapiroomTextView txtNewsTitle = (PapiroomTextView) findViewById(R.id.txtNewsDetailTitle);
final ImageView imgNews = (ImageView) findViewById(R.id.imgNewsDetail);
final ImageView imgNewsVideo = (ImageView) findViewById(R.id.imgNewsDetailVideo);
final PapiroomTextView txtNewsContent = (PapiroomTextView) findViewById(R.id.txtNewsDetailContent);
final PapiroomTextView txtNewsApplaudCount = (PapiroomTextView) findViewById(R.id.txtNewsDetailApplaudCount);
final PapiroomTextView txtNewsCommentCount = (PapiroomTextView) findViewById(R.id.txtNewsDetailCommentCount);
final PapiroomTextView txtNewsAnnounceCount = (PapiroomTextView) findViewById(R.id.txtNewsDetailAnnounceCount);
final FrameLayout containerApplaud = (FrameLayout) findViewById(R.id.layoutApplaud);
final FrameLayout containerAnnounce = (FrameLayout) findViewById(R.id.layoutAnnounce);
final FrameLayout containerMore = (FrameLayout) findViewById(R.id.layoutMore);
final ImageView imgNewsMore = (ImageView) findViewById(R.id.imgMore);
final ImageView btnNewsDetailComment = (ImageView) findViewById(R.id.btnNewsDetailComment);
final LinearListView listComment = (LinearListView) findViewById(R.id.listNewsDetailComment);
final PapiroomAutoCompleteTextView txtNewsDetailComment = (PapiroomAutoCompleteTextView) findViewById(R.id.txtNewsDetailComment);
final NewsImage image = news != null ? news.getImage() : null;
final float height = image != null ? calculate(image.getWidth(), image.getHeight()) : 0f;
if(height >= 2000) imgNews.setScaleType(ScaleType.CENTER_CROP);
imgNews.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, (int) height));
imgNews.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
onImageClicked(news);
}
});
if(news.isVideo()) {
imgNewsVideo.setVisibility(View.VISIBLE);
imgNewsVideo.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
onImageClicked(news);
}
});
}
txtNewsContent.setMovementMethod(new PapiroomMovementMethod());
txtNewsApplaudCount.setText(news.getApplaudCount());
txtNewsApplaudCount.setOnClickListener(new ApplaudCounterClickListener(this, news));
txtNewsCommentCount.setText(news.getCommentCount());
txtNewsAnnounceCount.setText(news.getAnnounceCount());
txtNewsAnnounceCount.setOnClickListener(new AnnounceCounterClickListener(this, news));
// Applaud View Imp.
containerApplaud.setVisibility(news.isHidden() ? View.GONE : View.VISIBLE);
containerApplaud.setBackgroundResource(news.isApplauded() ? R.drawable.bg_circular_active : R.drawable.bg_circular_passive);
containerApplaud.setOnTouchListener(new PapiroomButtonOnTouchListener(containerApplaud, new ApplaudButtonClickListener(this, news, containerApplaud, txtNewsApplaudCount, true)));
// Announce View Imp.
containerAnnounce.setVisibility(news.isHidden() || news.getAuthor().getUserId() == MainActivity.getUser().getUserId() ? View.GONE : View.VISIBLE);
containerAnnounce.setBackgroundResource(news.isAnnounced() ? R.drawable.bg_circular_active : R.drawable.bg_circular_passive);
containerAnnounce.setOnTouchListener(new PapiroomButtonOnTouchListener(containerAnnounce, new AnnounceButtonClickListener(this, news, containerAnnounce, txtNewsAnnounceCount)));
imgNewsMore.setImageResource(R.drawable.ic_more);
containerMore.setOnTouchListener(new PapiroomButtonOnTouchListener(containerMore, new MoreButtonClickListener(this, news)));
//final MentionAdapter adapter = new MentionAdapter(this, new ArrayList<User>());
//adapter.setNotifyOnChange(true);
// If comment btn was triggered from previous activity
if(isWillingToComment) txtNewsDetailComment.requestFocus();
imgNewsUser.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
goToUserPage(news);
}
});
final MentionTextWatcher watcher = new MentionTextWatcher(null, btnNewsDetailComment);
txtNewsDetailComment.addTextChangedListener(watcher);
if(!news.isViewed()) new IncreaseViewCountTask(this, news).execute();
// Initialization
final CommentAdapter commentAdapter = new CommentAdapter(this, news.getAuthor().getUserId(), txtNewsDetailComment, news, listComment);
listComment.setDividerDrawable(null);
listComment.setAdapter(commentAdapter);
btnNewsDetailComment.setOnClickListener(new PostCommentButtonClickListener(this, commentAdapter, txtNewsDetailComment, news.getFeedId(), scrollView));
new GetLastCommentsTask(this, listComment, commentAdapter, news).execute();
if(news != null) {
final User author = news.getAuthor();
PapiroomApplication.getImageLoader().displayImage(author.getProfileImageUrl(), imgNewsUser, PapiroomApplication.getOptionsUser());
txtViewCount.setText(news.getViewCount());
txtNewspaperName.setText(author.getNewspaperName() != null ? author.getNewspaperName() : news.getOwnerNewspaperName());
txtNewsUsername.setText(author.getUsername() != null ? "@" + author.getUsername() : "@" + news.getOwnerUserName());
txtNewsDate.setText(DateTimeUtils.getFormattedDateString(news.getDate()));
txtNewsTitle.setText(news.getTitle());
PapiroomApplication.getImageLoader().displayImage(news.getImage().getURL(), imgNews, PapiroomApplication.getOptionsNews());
txtNewsContent.setText(Html.fromHtml(news.getContent()));
}
}
private void onImageClicked(News news) {
final String videoUrl = news.getVideoUrl();
final String imageUrl = news.getImage().getURL();
Intent intent;
if(news.isVideo()) {
intent = new Intent(this, WebViewActivity.class);
intent.putExtra(WebViewActivity.KEY_URL, videoUrl);
}
else {
intent = new Intent(this, FullScreenPhotoActivity.class);
intent.putExtra(FullScreenPhotoActivity.KEY_URL, imageUrl);
}
this.startActivity(intent);
this.overridePendingTransition(R.anim.activity_open_translate, R.anim.activity_close_scale);
}
private float calculate(int w, int h) {
if(h > 0) {
final float scale = (float) h / (float) w;
final float calculated = (scale > 0f) ? (containerWidth * scale) : 0;
return (calculated > 2000) ? 2000 : calculated;
}
else return 0;
}
private void goToUserPage(News news) {
// Go To User Page
final long userId = news.getAuthor().getUserId();
if(userId != ProfileActivity.userId) {
final String newspaperName = news.getAuthor().getNewspaperName();
final Intent intent = new Intent(this, ProfileActivity.class);
intent.putExtra(ProfileActivity.KEY_UID, userId);
intent.putExtra(ProfileActivity.KEY_NEWSPAPER_NAME, newspaperName);
startActivity(intent);
overridePendingTransition(R.anim.activity_open_translate, R.anim.activity_close_scale);
}
}
@Override
public void onResume() {
super.onResume();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
final int id = item.getItemId();
switch (id) {
case android.R.id.home:
finish();
break;
}
return super.onOptionsItemSelected(item);
}
@Override
public void finish() {
super.finish();
overridePendingTransition(R.anim.activity_open_scale, R.anim.activity_close_translate);
}
}
我更喜欢使用广播接收机
最近一个面试官问了我一个很棘手的问题。这个问题有几个部分。 为什么(问题是为什么,而不是如何)需要在从一个活动发送到另一个活动时打包对象,而不是直接发送 我给的答案- Parcelable为开发人员提供了限制对象创建的能力,这在某种程度上使其使用速度更快。 我没有得到任何有用的链接后,谷歌,而且我或面试官不太满意的答案。如果你们能帮忙,那就太好了!
假设我有这门课: 以及子类: 我知道这是不可能的,但我想你明白我想要什么。如果Foobar实现了Cloneable,并且没有扩展AbstractFoo,那么子类就可以工作。我想我想要但不允许的是: 如果Foobar实现了Cloneable,并且没有扩展AbstractFoo,那么子类就可以工作。 除了扩展的抽象类,我怎么能做到“相同”?
我正在开发一个由多个活动组成的Android应用程序,我必须在它们之间传递ab对象,但我不能通过使用意图传递它,因为对象的类没有实现可序列化,我怎么做?我无法修改我的类的源代码。谢谢:)
我试图在包含对象ArrayList的类上使用Parcelable。 更新:Station现在也实现了Parcelable,正如Naveen Dew所建议的那样。 车站等级- 当我把图书馆的包裹递给“为声音而制造”服务时,我遇到了一个问题。 java.lang.RuntimeException:无法使用意图启动服务com.tsuryohananov.IsrailiRadio.BackgroundSo
我正在使用一个可打包对象来传递一个意图。我的对象看起来是这样的 公共类配方实现Parcelable{private List Recipe=null;private List firedents=null;private String preparation; 我调试了这部分代码,我知道sendRecipe对象是实例化的,数据是正确的。所以我把这个东西放在意向性上,然后把它发送到下一个活动 在这个
因此,有一个的实例,其中为空,这正是Jackson返回的内容: 我希望json没有空括号: 这个问题对我没有帮助: null