活动克隆之间的Android Parcelable对象

时间:2015-03-10 19:34:18

标签: java android object synchronization parcelable

我有一个类,它使用所有必需的读写方法实现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。单击列表项时,我将特定的parcelable对象传递给DetailActivity,我可以毫无问题地读取parcelable对象...现在一切都很完美.. BIG PROBLEM 从这里开始.. 当我更改此对象的任何属性(写入)时,我实际上只是更改了克隆而不是之前活动列表视图中保存的原始对象。 我认为发生此问题的原因是,Parcelable.Creator从parcel返回一个新对象而不是god对象引用。

只是克隆......

My NewsDetailActivity.class我在此活动中向对象写入新值......

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);
}
}

我该如何解决这个问题?

对不起我的英文:)

1 个答案:

答案 0 :(得分:0)

我更喜欢使用BroadcastReceivers