Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/180.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java,使用接口作为回调_Java_Android_Interface_Callback_Touch - Fatal编程技术网

Java,使用接口作为回调

Java,使用接口作为回调,java,android,interface,callback,touch,Java,Android,Interface,Callback,Touch,我一直在为Android开发一个简单的触摸处理程序,它可以在不需要设置线程的情况下启动onUpdate之类的回调(当触摸屏幕时)。我的问题是,我对Java的知识相当有限,我无法做到这一点,因为我对如何使用接口知之甚少。我很确定我的问题可能是一个简单的输入错误或其他什么,但是当我从触摸处理程序(处理触摸信息)执行方法时,我得到了一个NullPointerException,这样我就可以在主activity类中执行我需要的操作 这是主要的类代码(从不相关的内容中删除): 我希望这个问题不会太离谱,不

我一直在为Android开发一个简单的触摸处理程序,它可以在不需要设置线程的情况下启动onUpdate之类的回调(当触摸屏幕时)。我的问题是,我对Java的知识相当有限,我无法做到这一点,因为我对如何使用接口知之甚少。我很确定我的问题可能是一个简单的输入错误或其他什么,但是当我从触摸处理程序(处理触摸信息)执行方法时,我得到了一个NullPointerException,这样我就可以在主activity类中执行我需要的操作

这是主要的类代码(从不相关的内容中删除):

我希望这个问题不会太离谱,不会发到这里:)


编辑:感谢所有人的帮助,最后我采用了Bughi的解决方案。

如果NullPointerException出现在这里:

helper.onTouchUpdate(pointerId);
然后简单地
helper
为空,在哪里初始化它

我看到你定义了它:

TouchHelper helper;
但是你有过吗

helper = ...

TouchReader
中定义
TouchHelper
,但代码中没有创建对象或将现有对象指定给该属性。因此,当您尝试使用它时,它仍然为空。

helper
在您的in
TouchReader中为空

要解决此问题,请让
TouchReader
使用
TouchHelper

public TouchReader(View view, TouchHelper helper) {
    ...
    this.helper = helper;   
    ...
}
然后在您的活动中:

touchReader = new TouchReader(textView, this);

尝试在构造函数中初始化它;所有未初始化的引用都设置为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;
}
//我看不出为什么这应该是一个成员变量;让它成为本地的
StringBuilder=新的StringBuilder();
文本视图文本视图;
触摸阅读器触摸阅读器;
列表数组;
触摸台触摸台;
公共TouchReader(视图)
{
//textView为空
//touchReader为空
view.setOnTouchListener(这个);
//为什么是“10”?
touchTables=新的ArrayList(10);
Log.d(标记“TouchReader已初始化”);
//touchTable为空;
}

您的
触摸助手
为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;
}

我知道这很老了,但我自己也被困在这上面了。山姆在上面的帖子帮助我想到了这一点。
最后,我添加了一个onAttach方法,用于检查接口是否已初始化,以及是否已实现到与之接口的主活动。我在要测试的主要活动中添加了一个日志

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

谢谢,这很有效。显然,这个错误很愚蠢,但因为我知道“实例化”接口的工作方式与普通类不同,所以我就丢失了。10因为我在试验ArrayList,我选择了这个值,因为,尝试在手机上放置超过10个手指:/touchTable成员变量是一个缓冲区,我在上面写入数据,然后将其保存到ArrayList。也许不是最有效的方法,但它是迄今为止最简单的。正如我所指出的,你还有很多其他问题。你最好解决这些问题。你是新来的,所以你应该知道,这对你和那些花时间投票选出有用答案并接受回答你问题的最佳答案的人都有好处。如果你是指你的其他评论,我会在构造函数或代码的其他部分给这些变量一个值。使侦听器工作后,代码工作得非常完美如果我知道如何做,我会看到向上箭头吗?点击他们投票表决一个答案。看到每个答案旁边的复选标记了吗?单击最能回答您问题的选项旁边的选项。
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;
}
@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    try {
        mainActivityCallback = (OnSomethingSelectedListener) activity;
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString()
                + " must implement OnSomethingSelectedListener");
    }
}