Java安卓学习总结(九)

第5章 activity间数据的传递

关于创建和启动新的activity

Android Studio下新建activity似乎没有eclipse下的子activity的从属的概念。每一个activity之间,除了launcher activity,似乎都是平行的,没有谁一定属于谁,只有相互调用的关系。

在一个activity中调用另一个activity时,是将调用请求发送给操作系统的ActivityManager,ActivityManager根据接收到的Intent参数(类似于Windows编程中的句柄??)来创建activity实例。

有关activity之间的值传递

这和onSaveInstanceState()方法类似,都是将要传递的信息映射到字符串键上。在activity之间传递数据要用intent extra。将extra的信息添加给intent的方法为intent.putExtra(),类比savedInstaceState.putXXX()。获取extra信息的方法为getXXXExtra(),类比savedInstaceState.getXXX()。

主activity向子activity传递数据的过程是:先实例化一个intent对象并将需要传递的数据存储进intent,然后使用该intent和专门的请求代码来向ActivityManager申请创造子activity,最后新建的子activity可以解析传递来的extra。

子activity向主activity传递数据的过程是:实例化intent对象并将需要传递的数据存储进intent,然后调用setResult()方法将结果打包,主activity会根据之前的请求代码来调用onActivityResult()方法,解析传回来的结果。解析的过程不做细致描述。

我今天在尝试的时候,发现点击完作弊之后主Activity没有接收到任何作弊提示,原因就是在于没有将Intent参数传入setResult()方法中。

没有传入Intent参数
正确写法

在onActivityResult()方法要注意请求代码是否匹配,返回代码是否符合预期(OK/CANCEL),因为“实践证明,这样做会方便将来代码的维护”。

有关tools与tools:text

这个tools感觉就是在开发过程中使用的可以预先实现一些功能的工具,很像存根程序或驱动程序。这个帖子详细地讲解了tools的作用。

这里的tools:text是覆盖掉这个控件的Android:text,并且使得text内的内容在预览时可见而在实际运行时不可见。

有关挑战练习:堵住漏洞

用户作弊后,可以旋转CheatActivity来清除作弊痕迹

同一个activity内在旋转屏幕前后要保存数据,就如同之前的做法一样将数据保存到一个键值对里面,在重写onSaveInstanceState()方法存储就可以了。

定义一个成员变量来记录此次activity是否作弊了(点击查看答案按钮)。

private boolean mCheated;
protected void  onSaveInstanceState(Bundle saveInstanceState)
    {
        super.onSaveInstanceState(saveInstanceState);
        saveInstanceState.putBoolean(KEY_CHEAT,mCheated);

    }

之前一直纠结要不要给成员变量初始化的问题,其实不需要,因为在再次接受mCheated时,如果其为空会给它缺省值。

mCheated=savedInstanceState.getBoolean(KEY_CHEAT,false);

每次通过解析得到mCheat时,要重新调用setAnswerShownResult();方法将结果写入extra中,并且判断是否已经作弊了,由此来决定文本框内容。

if (savedInstanceState!=null)
        {
            mCheated=savedInstanceState.getBoolean(KEY_CHEAT,false);
            setAnswerShownResult(mCheated);
            if (mCheated)
            {
                if (mAnswerIsTrue)
                {
                    mAnswerTextView.setText(R.string.true_button);
                }
                else
                {
                    mAnswerTextView.setText(R.string.false_button);
                }
            }
        }

作弊返回后,用户可以旋转QuizActivity来清除mIsCheated变量值

同上。

用户可以不断单击NEXT按钮,跳到偷看过答案的问题,从而使作弊记录丢失

这个问题是怎么来的呢?因为先前每一次点击next按钮时,mIsCheated默认被赋值为false,只要点击next其值就会被自动刷新为false。

参考当时处理此题是否被回答过的情况,完全一样的做法,给question类再增加一个成员变量,每一次点击next时,根据题目编号来赋值mIsCheated。

public class Question {
    private int mTextResId;
    private boolean mAnswerTrue;
    private boolean mAnswered;
    private boolean mIsCheated;
    public Question(int TextResId, boolean AnswerTrue,boolean Answered,boolean IsCheated)
    {
        mTextResId=TextResId;
        mAnswerTrue=AnswerTrue;
        mAnswered=Answered;
        mIsCheated=IsCheated;
    }
//...
}

再将是否作弊的结果保存到键值对里面即可。

每一次作弊完之后都要更新这个成员变量。我在试验时发现好像还是没成功。。。因为我没把是否作弊的结果存到数组里面。。

@Override
    protected void onActivityResult(int requestCode,int resultCode,Intent data)
    {
        if (resultCode!=RESULT_OK)
        {
            return;
        }
        if (requestCode==REQUEST_CODE_CHEAT)
        {
            if (data==null)
            {
                return;
            }
            mIsCheater=CheatActivity.wasAnswerShown(data);
            //此处一定要更新
            mQuestionBank[mCurrentIndex].setCheated(mIsCheater);
        }
    }

发表评论