Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/403.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_Function_Interface_Parameters - Fatal编程技术网

在java中作为参数传递函数

在java中作为参数传递函数,java,android,function,interface,parameters,Java,Android,Function,Interface,Parameters,我对Android框架和Java越来越熟悉,希望创建一个通用的“NetworkHelper”类,该类将处理大多数网络代码,使我能够从中调用网页 我根据developer.android.com上的这篇文章创建了我的网络类: 代码: 我遇到的问题是,我应该以某种方式回调该活动,并且它应该可以在“downloadUrl()”函数中定义。例如,下载完成后,将调用活动中的public void“handleWebpage(字符串数据)”函数,并将加载的字符串作为其参数 我在谷歌上搜索了一下,发现我应该

我对Android框架和Java越来越熟悉,希望创建一个通用的“NetworkHelper”类,该类将处理大多数网络代码,使我能够从中调用网页

我根据developer.android.com上的这篇文章创建了我的网络类:

代码:

我遇到的问题是,我应该以某种方式回调该活动,并且它应该可以在“downloadUrl()”函数中定义。例如,下载完成后,将调用活动中的public void“handleWebpage(字符串数据)”函数,并将加载的字符串作为其参数

我在谷歌上搜索了一下,发现我应该以某种方式使用接口来实现这个功能。在回顾了几个类似的stackoverflow问题/答案之后,我没有让它工作,我不确定我是否正确理解了接口:老实说,使用匿名类对我来说是新的,我不确定我应该在所提到的线程中应用示例代码片段的位置或方式

所以我的问题是如何将回调函数传递给我的网络类,并在下载完成后调用它?接口声明在哪里,实现关键字等等?
请注意,我是Java初学者(虽然有其他编程背景),所以我希望能有一个完整的解释:)谢谢

将回调接口或抽象类与抽象回调方法一起使用

回调接口示例:

public class SampleActivity extends Activity {

    //define callback interface
    interface MyCallbackInterface {

        void onDownloadFinished(String result);
    }

    //your method slightly modified to take callback into account 
    public void downloadUrl(String stringUrl, MyCallbackInterface callback) {
        new DownloadWebpageTask(callback).execute(stringUrl);
    }

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

        //example to modified downloadUrl method
        downloadUrl("http://google.com", new MyCallbackInterface() {

            @Override
            public void onDownloadFinished(String result) {
                // Do something when download finished
            }
        });
    }

    //your async task class
    private class DownloadWebpageTask extends AsyncTask<String, Void, String> {

        final MyCallbackInterface callback;

        DownloadWebpageTask(MyCallbackInterface callback) {
            this.callback = callback;
        }

        @Override
        protected void onPostExecute(String result) {
            callback.onDownloadFinished(result);
        }

        //except for this leave your code for this class untouched...
    }
}

是的,界面是IMHO的最佳方式。例如,GWT使用命令模式和如下界面:

public interface Command{
    void execute();
}
通过这种方式,您可以将函数从一个方法传递到另一个方法

public void foo(Command cmd){
  ...
  cmd.execute();
}

public void bar(){
  foo(new Command(){
     void execute(){
        //do something
     }
  });
}

开箱即用的解决方案是,这在Java中是不可能的。Java不接受。这可以通过一些“技巧”来实现。通常情况下,界面就是您看到的界面。请查看更多信息。您也可以使用反射来实现它,但这很容易出错。

在Java编码体系结构中,使用接口可能是最好的方法

但是,传递一个可运行的对象也可以工作,我认为这将更加实用和灵活

 SomeProcess sp;

 public void initSomeProcess(Runnable callbackProcessOnFailed) {
     final Runnable runOnFailed = callbackProcessOnFailed; 
     sp = new SomeProcess();
     sp.settingSomeVars = someVars;
     sp.setProcessListener = new SomeProcessListener() {
          public void OnDone() {
             Log.d(TAG,"done");
          }
          public void OnFailed(){
             Log.d(TAG,"failed");
             //call callback if it is set
             if (runOnFailed!=null) {
               Handler h = new Handler();
               h.post(runOnFailed);
             }
          }               
     };
}

/****/

initSomeProcess(new Runnable() {
   @Override
   public void run() {
       /* callback routines here */
   }
});

反射从来都不是一个好主意,因为它更难阅读和调试,但是如果你100%确定你在做什么,你可以简单地调用像set_method(R.id.button_profile_edit,“toggle_edit”)这样的方法将方法附加到视图上。这在片段中是有用的,但是再一次,一些人会认为它是反模式,所以要警告。
public void set_method(int id, final String a_method)
{
    set_listener(id, new View.OnClickListener() {
        public void onClick(View v) {
            try {
                Method method = fragment.getClass().getMethod(a_method, null);
                method.invoke(fragment, null);
            } catch (Exception e) {
                Debug.log_exception(e, "METHOD");
            }
        }
    });
}
public void set_listener(int id, View.OnClickListener listener)
{
    if (root == null) {
        Debug.log("WARNING fragment", "root is null - listener not set");
        return;
    }
    View view = root.findViewById(id);
    view.setOnClickListener(listener);
}

不需要接口,不需要库,不需要Java 8

只需从
java.util.concurrent

public static void superMethod(String simpleParam, Callable<Void> methodParam) {

    //your logic code [...]

    //call methodParam
    try {
        methodParam.call();

    } catch (Exception e) {
        e.printStackTrace();
    }
}
publicstaticvoidsupermethod(字符串simpleParam,可调用methodParam){
//您的逻辑代码[…]
//调用methodParam
试一试{
methodParam.call();
}捕获(例外e){
e、 printStackTrace();
}
}
如何使用它:

superMethod(“helloworld”,newcallable()){
公开作废通知(){
myParamMethod();
返回null;
}
}
);

其中,
myparamethod()
是我们作为参数传递的方法(在本例中,
methodParam
)。

这不值得作为答案,因为您所做的一切都表明,作为注释,调查什么更合适。因为他只有不到50个代表,所以他不能评论,只能回答。我一直不喜欢这样。这是一个非常有用的概念性答案,对于有经验的程序员来说。谢谢,奥洛林!谢谢,这帮助我解决了这个问题,我想我现在已经了解了接口的基础知识:)有趣的是,看看接口在普通java编程中是如何发挥重要作用的。GWT是什么,以及如何传递任何参数?@Buksy这是你要找的吗?公共接口命令{void execute(Object…Object);}传递无限对象:DVery clean和niat实现。感谢您的回答。然而,这个例子并没有明确说明(我已经熬夜了,所以请原谅我的糊涂问题)myParamMethod是如何通过simpleParam的。例如,我在Ion周围有一个包装器,我将服务器参数和用Json封装的目标URL传递给它,我是否使用超级方法(serverParams,callEndpointIon);或者我每次都必须覆盖可调用吗?如果您使用的是
Callable
,那么没有真正的理由不使用
Runnable
,因为您仍然返回Void。它将不再需要
返回null语句。。。。(并且没有输入参数)如何将参数传递给可调用的methodParam.call(对象);并接收公共Void调用(JSONObject对象){//myParamMethod(JSONObject对象);返回null;}
public void foo(Command cmd){
  ...
  cmd.execute();
}

public void bar(){
  foo(new Command(){
     void execute(){
        //do something
     }
  });
}
 SomeProcess sp;

 public void initSomeProcess(Runnable callbackProcessOnFailed) {
     final Runnable runOnFailed = callbackProcessOnFailed; 
     sp = new SomeProcess();
     sp.settingSomeVars = someVars;
     sp.setProcessListener = new SomeProcessListener() {
          public void OnDone() {
             Log.d(TAG,"done");
          }
          public void OnFailed(){
             Log.d(TAG,"failed");
             //call callback if it is set
             if (runOnFailed!=null) {
               Handler h = new Handler();
               h.post(runOnFailed);
             }
          }               
     };
}

/****/

initSomeProcess(new Runnable() {
   @Override
   public void run() {
       /* callback routines here */
   }
});
public void set_method(int id, final String a_method)
{
    set_listener(id, new View.OnClickListener() {
        public void onClick(View v) {
            try {
                Method method = fragment.getClass().getMethod(a_method, null);
                method.invoke(fragment, null);
            } catch (Exception e) {
                Debug.log_exception(e, "METHOD");
            }
        }
    });
}
public void set_listener(int id, View.OnClickListener listener)
{
    if (root == null) {
        Debug.log("WARNING fragment", "root is null - listener not set");
        return;
    }
    View view = root.findViewById(id);
    view.setOnClickListener(listener);
}
public static void superMethod(String simpleParam, Callable<Void> methodParam) {

    //your logic code [...]

    //call methodParam
    try {
        methodParam.call();

    } catch (Exception e) {
        e.printStackTrace();
    }
}
 superMethod("Hello world", new Callable<Void>() {
                public Void call() {
                    myParamMethod();
                    return null;
                }
            }
    );