【问题标题】:Unable to update TextView with Timer in separate class无法在单独的类中使用 Timer 更新 TextView
【发布时间】:2017-02-24 17:34:28
【问题描述】:

我创建了一个计时器并将其放置在自己的单独类中。由于某种原因,当我尝试运行它时它会崩溃并出现以下错误:

Java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“void android.widget.TextView.setText(java.lang.CharSequence)”

我认为是因为它试图从 Mainactvity 以外的类更新文本视图,但我不知道如何让它工作。

代码如下:

主活动

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

Button resetButton;
TextView textTimer;
int elapsedTime;



@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    elapsedTime = 60;


    textTimer = (TextView) findViewById(R.id.textTimer);
    resetButton = (Button) findViewById(R.id.resetButton);

    final Button resetbttn = (Button) findViewById(R.id.resetButton);
    resetbttn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            CountUp mycountup = new CountUp();
            mycountup.count();
        }
    });

}

}

定时器类:

 import android.content.Context;
 import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

/** * 由 Mat 于 17 年 2 月 24 日创建。 */

public class CountUp extends MainActivity{




TextView textTimer;
Button resetButton;
int elapsedTime;
Handler h;
int RATE = 1000;
MainActivity mainact = new MainActivity();




@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

textTimer = (TextView) findViewById(R.id.textTimer);
resetButton = (Button) findViewById(R.id.resetButton);



h = new Handler();

count();

final Button resetbttn = (Button) findViewById(R.id.resetButton);
resetbttn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        reset();
    }
});
}

public void reset(){
    elapsedTime = 60000;
}




public void count(){
    elapsedTime--;
    textTimer.setText(String.valueOf(elapsedTime));
    h.postDelayed(r,RATE);
    final String endcomparison = textTimer.getText().toString();
    if (endcomparison.equals("0")){
        reset();
    }
}
private Runnable r = new Runnable() {
    @Override
    public void run() {
        count();
    }
};



}

【问题讨论】:

  • 我想我现在已经把它移开了。我在主要活动中添加了以下内容:“public static TextView hourtext;”和“hourtext = (TextView) findViewById(R.id.SessionTimerTxt);”。在计时器类中,我已将此“hourtext.setText (String.valueOf(elapsedTime))”更改为“MainActivity.hourtext.setText(String.valueOf(elapsedTime));”。我现在得到一个不同的错误,即“java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法'boolean android.os.Handler.postDelayed(java.lang.Runnable,long)'”帮助!!!

标签: java android class timer textview


【解决方案1】:

findViewById() 方法实际上是在布局文件中查找视图。 当您使用

设置活动或片段的布局时

setContentView(R.layout.activity_main);

findViewById() 在该布局中查找那些视图。它无法即时找到随机对象。

所以在第二个活动中首先设置布局或在第一个活动中创建子类,然后尝试在 textview 中更新数据。

【讨论】:

  • 您好 androidnoobdev,感谢您的回复。好吧,所以我必须识别布局,然后它就会知道在哪里搜索视图 ID。我会试一试,看看它是否有效。所以基本上我只需要添加这个“setContentView(R.layout.activity_main);”到我的第二个活动,它应该工作:-)
  • @Matmajot Ya 但这将显示该布局。我的意思是 2 次你会看到相同的布局。所以你宁愿将文本视图对象传递给第二类,然后更新它。
  • 好的,那么我如何将该 textview 对象传递给第二个类,你能给我举个例子吗?谢谢
【解决方案2】:

您只是在实例化一个活动,它的 onCreate 永远不会被调用。

CountUp mycountup = new CountUp();
mycountup.count(); // view never created so it's null

要加载视图,您需要使用startActivity 之类的方法。

如果我对您的理解正确,如果您是从 MainActivity 扩展 CountUp,那么在您的清单中,您应该将 CountUp 设置为您的启动活动。然后使用Java继承,就不需要重新查找视图了,因为在CountUp中我们调用的是super.onCreate(savedInstanceState),它调用了MainActivity的onCreate。

public class MainActivity extends AppCompatActivity {

Button resetButton;
TextView textTimer;
int elapsedTime;

@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);

  elapsedTime = 60;
  textTimer = (TextView) findViewById(R.id.textTimer);
  resetButton = (Button) findViewById(R.id.resetButton);
  }
 }

public class CountUp extends MainActivity{
  Handler h;
  int RATE = 1000;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // can access this since inheritance
    resetButton.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View view) {
          reset();
      }
   });
    h = new Handler();
    count();
  }

//...

public void count(){
  elapsedTime--;

  // inheritance   
  textTimer.setText(String.valueOf(elapsedTime));
  h.postDelayed(r,RATE);
  final String endcomparison = textTimer.getText().toString();
  if (endcomparison.equals("0")){
      reset();
  }
 }
 //...
}

【讨论】:

  • 您好 Ekeitho,感谢您的回复。看起来您刚刚将计时器代码放入 mainActivity 中?如果我想避免这种情况,因为我会有几个不同的计时器,而且 MainActivity 中的代码会很大!
  • 好的,知道你现在想要做什么了。那么您的 CountUp 类不需要从 Activity 扩展。您的 CountUp 只需要一个对 Activity 的引用,例如将其传递给您的 CountUp 构造函数并在 CountUp 中改变您的视图。希望这会有所帮助。
  • 你有机会提供一个例子吗?
猜你喜欢
  • 2016-04-23
  • 1970-01-01
  • 2013-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-20
  • 1970-01-01
相关资源
最近更新 更多