更改postDelayed正在调用的runnable类中的Textview

时间:2015-03-18 14:43:31

标签: android google-glass google-gdk

我有一个Runnable类,它最终会改变textview的文本和颜色,具体取决于它从SharedPreferences获得的某个值。

我尝试在最初调用runnable的类中创建类,这很好用,现在我想把这个类放在它自己的类文件中以保持它干净并且能够从其他类中轻松访问它

但是我现在得到了一个nullpointer,在评论了一些代码后,看起来像textview导致了这个问题。

这是我的班级

public class SettingsRunnable extends Activity implements Runnable {
View mView;
SharedPreferences mSettings;
SharedPreferences.Editor mEditSettings;
TextView mText;
CardScrollView mCardScroller;

public SettingsRunnable(View view, TextView text, SharedPreferences settings, CardScrollView cardView)
{
    this.mView = view;
    this.mText = text;
    this.mSettings = settings;
    this.mCardScroller = cardView;
    mEditSettings = mSettings.edit();
}

@Override
public void run() {
    try {
        if(mView == null)
        {
            mView = mCardScroller.getSelectedView();
        }
        String status = "";
        if (mSettings.contains("headgesture")) {
            status = mSettings.getString("headgesture", "");
            mText.setText(status);
            switch (status) {
                case "on":
                    mText.setTextColor(getResources().getColor(R.color.status_on));
                    break;
                case "off":
                    mText.setTextColor(getRecources().getColor(R.color.status_off));
                    break;
            }
        }
        if (mSettings.contains("network")) {
            status = mSettings.getString("network", "");
            //mText.setText(status);
            switch (status) {
                case "always":
                    break;
                case "wifi":
                    break;
                case "never":
                    break;
            }
        }
        mView.setTag(mText);
    }
    catch(Exception e)
    {
        Log.wtf("ErrorRun", e.getMessage());
    }
}
}

然后我在尝试调用它的类中的onCreate()中有以下内容。

mCards = new ArrayList<>();
    //android.os.Debug.waitForDebugger();
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
getWindow().requestFeature(WindowUtils.FEATURE_VOICE_COMMANDS); 

CreateCards();//is being used to add cards to the mCards list, these cards will be inflated in the mainAdapter

mCardScroller = new CardScrollView(this);
mCardScroller.setAdapter(new mainAdapter(mCards, getLayoutInflater()));

mCardScroller.setOnItemClickListener(this);

mGestureDetector = createGestureDetector(this);
card = new CardPosition(mCardScroller);//is being used to get the current position of the cardscroller
setContentView(mCardScroller);
settings = getSharedPreferences(PREFERENCE, PRIVATE);
view = new View(this);
mText = (TextView) findViewById(R.id.headgesture_status);
setR = new SettingsRunnable(view, mText, settings, mCardScroller);
handler.postDelayed(setR, 1000);

修改

6086-6086/com.example.sw_stage.glass E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.sw_stage.glass, PID: 6086
java.lang.NullPointerException
        at com.example.sw_stage.glass.Runnables.SettingsRunnable.run(SettingsRunnable.java:42)
        at android.os.Handler.handleCallback(Handler.java:733)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:149)
        at android.app.ActivityThread.main(ActivityThread.java:5045)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
        at dalvik.system.NativeStart.main(Native Method)

编辑2

似乎当我尝试在onCreate中获取textview时,它返回null。我不完全确定为什么会这样。视图应该已经膨胀并设置在调用它的位置。实际上,当我输入此代码以快速测试它时,它完美地运行。然而,它是肮脏的当然

settings = getSharedPreferences(PREFERENCE, PRIVATE);
    view = new View(this);
    mText = (TextView) findViewById(R.id.headgesture_status);
    //handler.postDelayed(setR, 1000);
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            mText = (TextView) findViewById(R.id.headgesture_status);
            setR = new SettingsRunnable(view, mText, settings, mCardScroller, false);
            handler.postDelayed(setR,0);
        }
    },0);

XML文件

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:background="@color/main_background">

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/settings_headgesture"
    android:gravity="center"
    android:textSize="47pt"/>
<TextView
    android:layout_height="wrap_content"
    android:layout_width="wrap_content"
    android:textAllCaps="true"
    android:textStyle="bold|italic"
    android:gravity="center"
    android:textSize="47pt"
    android:id="@+id/headgesture_status"/>

</LinearLayout>

2 个答案:

答案 0 :(得分:2)

实例化活动不是一个好主意,因为Android管理活动生命周期。此外,我不认为你应该扩展Activity并实现Runnable。

我建议你可以在一个单独的类中创建runnable并在onCreate中实例化它。另外,您可以考虑将一些相关代码从构造函数移动到onCreate。

修改

我已检查过Android源代码。根据我的理解,您的代码应抛出java.lang.InstantiationException因为您的Activity没有零参数构造函数。 (Android uses reflection to instantiate activity and the zero argument constructor is required.

我不确定为什么你可以在Glass上侥幸逃脱。无论如何,正如我所提到的,你应该将runnable与另一个类分开,并将代码从构造函数移到onCreate。

请参阅

答案 1 :(得分:0)

我认为问题在于您正在对属于未在Runnable类中夸大的布局的文本视图进行更改。我还没有测试过以下代码,但您可能会发现它有用:

LayoutInflater inflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
View mView = inflater.inflate(R.layout.<your XML file>, null);
mText = (TextView) mView.findViewById(R.id.headgesture_status);

代码显式地扩展了布局XML文件,因此您可以获取文本视图。

答案基于Cristian的回答herehere