Java,使用接口作为回调

时间:2012-07-21 17:33:39

标签: java android interface callback touch

我一直在为Android开发一个简单的触摸处理程序,可以触发像onUpdate这样的回调(当触摸屏幕时)而无需设置线程。我的问题是我对Java的了解相当有限,我无法做到,因为我对如何使用接口知之甚少。我很确定我的问题可能是一个简单的拼写错误,但是当我从触摸处理程序(处理触摸信息)执行方法时,我得到一个NullPointerException,这样我就可以在主活动类中做我需要的

这是主类代码(从不相关的东西中删除):

//package and imports

public class Test extends Activity implements TouchHelper {

    StringBuilder builder = new StringBuilder();
    TextView textView;
    TouchReader touchReader;
    List<TouchTable> touchTablesArray;
    TouchTable touchTable;
    public static final String Tag = "TouchTest";

        @Override
        public void onCreate(Bundle savedInstanceState) 
        {
            super.onCreate(savedInstanceState);
            textView = new TextView(this);
            Log.d(Tag, "TextView initialized " + textView);
            textView.setText("Touch and drag (multiple fingers supported)!");
            touchReader = new TouchReader(textView);
            Log.d(Tag, "touchReader initialized");
            touchTablesArray = touchReader.getTouchTables();
            setContentView(textView);
        }

        @Override
        public void onTouchUpdate(int pointerId)
        {
            Log.d(Tag, "onTouchUpdate called");
            touchTable = touchTablesArray.get(pointerId);
            Log.d(Tag, "touchTable get successful");
            //writing on stringbuilder
        }
    }

这是处理程序本身的代码:

//package and imports

public class TouchReader implements OnTouchListener
{
    public final static String Tag = "TouchReader";
    List<TouchTable> touchTables;
    TouchHelper helper;
    TouchTable touchTable = new TouchTable();

    public TouchReader(View view)
    {
        view.setOnTouchListener(this);
        touchTables = new ArrayList<TouchTable>(10);
        Log.d(Tag, "TouchReader initialized");
    }

    public boolean onTouch(View v, MotionEvent event)
    {
        synchronized(this)
        {
            //all the common code handling the actual handling, with switches and such
            touchTables.add(pointerId, touchTable); //obviously the pointerId is defined earlier
            Log.d(Tag, "Values updated");
            helper.onTouchUpdate(pointerId); //the exception is here
            Log.d(Tag, "Update called");
        }
        return true;
    }
    public List<TouchTable> getTouchTables()
    {
        synchronized(this)
        {
            return touchTables;
        }
    }
}

正如您所看到的,错误很可能是由于我无法正确使用界面,但所有官方文档都让我更加困惑。

最后,界面的微小代码:

//package

public interface TouchHelper 
{
    public void onTouchUpdate(int pointerId);
}

我希望这个问题在这里发布不太苛刻:)

编辑:感谢大家的帮助,最后我跟随了Bughi的解决方案。

6 个答案:

答案 0 :(得分:4)

你的TouchHelper helper;为null,它需要一个接口实例才能调用它上面的方法 - 在你的情况下是实现你的接口的主要活动类 -

为侦听器设置set方法

public void setOnTouchListener(TouchHelper helper)
{
    this.helper = helper;
}

然后在创建时调用它:

public class Test extends Activity implements TouchHelper {
    ...
    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        ...
        touchReader = new TouchReader(textView);
        touchReader.setOnTouchListener(this);
        ...
    }
}

同时为您的触摸方法添加空检查:

public boolean onTouch(View v, MotionEvent event)
{
    synchronized(this)
    {
        //all the common code handling the actual handling, with switches and such
        touchTables.add(pointerId, touchTable); //obviously the pointerId is defined earlier
        Log.d(Tag, "Values updated");
        if (helper != null)
            helper.onTouchUpdate(pointerId); //the exception is here
        Log.d(Tag, "Update called");
    }
    return true;
}

答案 1 :(得分:2)

如果NullPointerException在这里:

helper.onTouchUpdate(pointerId);

然后只是helper为空,你在哪里初始化它?

我看到你定义它:

TouchHelper helper;

但你有过吗?

helper = ...

答案 2 :(得分:1)

我知道这已经过时了,但我自己也被困在了这一点上。 Sam的上述帖子让我想起了它 我最后添加了一个onAttach方法,该方法检查接口是否已初始化,以及是否与其接口的主活动实现。我在主要活动中添加了一个Log.i进行测试。

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    try {
        mainActivityCallback = (OnSomethingSelectedListener) activity;
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString()
                + " must implement OnSomethingSelectedListener");
    }
}

答案 3 :(得分:0)

TouchReader中,您定义了TouchHelper但在代码中没有任何地方创建对象或将现有对象分配给该属性。所以当你尝试使用它时它仍然是null。

答案 4 :(得分:0)

您在helper

中的

TouchReader为空

要解决此问题,请TouchReader选择TouchHelper

public TouchReader(View view, TouchHelper helper) {
    ...
    this.helper = helper;   
    ...
}

然后在你的活动中:

touchReader = new TouchReader(textView, this);

答案 5 :(得分:0)

尝试在构造函数中初始化它;所有未初始化的引用都设置为null。

// I see no reason why this should be a member variable; make it local
StringBuilder builder = new StringBuilder();
TextView textView;
TouchReader touchReader;
List<TouchTable> touchTablesArray;
TouchTable touchTable;
public TouchReader(View view)
{
    // textView is null
    // touchReader is null
    view.setOnTouchListener(this);
    // why "10"?  why a List of touchTables and a touchTable member variable?  why both?
    touchTables = new ArrayList<TouchTable>(10);
    Log.d(Tag, "TouchReader initialized");
    // touchTable is null;
}