java中将函数作为参数传递

2024-05-30

我正在熟悉 Android 框架和 Java,并希望创建一个通用的“NetworkHelper”类,该类将处理大部分网络代码,使我能够从中调用网页。

我按照developer.android.com 上的这篇文章创建了我的网络类:http://developer.android.com/training/basics/network-ops/connecting.html http://developer.android.com/training/basics/network-ops/connecting.html

Code:

package com.example.androidapp;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.util.Log;



/**
 * @author tuomas
 * This class provides basic helper functions and features for network communication.
 */


public class NetworkHelper 
{
private Context mContext;


public NetworkHelper(Context mContext)
{
    //get context
    this.mContext = mContext;
}


/**
 * Checks if the network connection is available.
 */
public boolean checkConnection()
{
    //checks if the network connection exists and works as should be
    ConnectivityManager connMgr = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();

    if (networkInfo != null && networkInfo.isConnected())
    {
        //network connection works
        Log.v("log", "Network connection works");
        return true;
    }
    else
    {
        //network connection won't work
        Log.v("log", "Network connection won't work");
        return false;
    }

}

public void downloadUrl(String stringUrl)
{
    new DownloadWebpageTask().execute(stringUrl);

}



//actual code to handle download
private class DownloadWebpageTask extends AsyncTask<String, Void, String>
{



    @Override
    protected String doInBackground(String... urls)
    {
        // params comes from the execute() call: params[0] is the url.
        try {
            return downloadUrl(urls[0]);
        } catch (IOException e) {
            return "Unable to retrieve web page. URL may be invalid.";
        }
    }

    // Given a URL, establishes an HttpUrlConnection and retrieves
    // the web page content as a InputStream, which it returns as
    // a string.
    private String downloadUrl(String myurl) throws IOException 
    {
        InputStream is = null;
        // Only display the first 500 characters of the retrieved
        // web page content.
        int len = 500;

        try {
            URL url = new URL(myurl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setReadTimeout(10000 );
            conn.setConnectTimeout(15000);
            conn.setRequestMethod("GET");
            conn.setDoInput(true);
            // Starts the query
            conn.connect();
            int response = conn.getResponseCode();
            Log.d("log", "The response is: " + response);
            is = conn.getInputStream();

            // Convert the InputStream into a string
            String contentAsString = readIt(is, len);
            return contentAsString;

        // Makes sure that the InputStream is closed after the app is
        // finished using it.
        } finally {
            if (is != null) {
                is.close();
            } 
        }
    }

    // Reads an InputStream and converts it to a String.
    public String readIt(InputStream stream, int len) throws IOException, UnsupportedEncodingException 
    {
        Reader reader = null;
        reader = new InputStreamReader(stream, "UTF-8");        
        char[] buffer = new char[len];
        reader.read(buffer);
        return new String(buffer);
    }


    // onPostExecute displays the results of the AsyncTask.
    @Override
    protected void onPostExecute(String result) 
    {
        //textView.setText(result);
        Log.v("log", result);

    }

} 

}

在我的活动课中,我以这种方式使用该课程:

connHelper = new NetworkHelper(this);

...

if (connHelper.checkConnection())
    {
        //connection ok, download the webpage from provided url
        connHelper.downloadUrl(stringUrl);
    }

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

我做了一些谷歌搜索,发现我应该以某种方式使用接口来实现此功能。在查看了一些类似的 stackoverflow 问题/答案后,我没有得到它的工作,我不确定我是否正确理解了接口:在 Java 中如何将方法作为参数传递? https://stackoverflow.com/questions/12616796/how-do-i-pass-method-as-a-parameter-in-java老实说,使用匿名类对我来说是新的,我不太确定应该在哪里或如何应用上述线程中的示例代码片段。

所以我的问题是如何将回调函数传递给我的网络类并在下载完成后调用它?接口声明、implements 关键字等在哪里? 请注意,我是 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...
    }
}

第二种选择更加简洁。您甚至不必为“onDownloaded 事件”定义一个抽象方法,如下所示onPostExecute正是需要的。只需扩展您的DownloadWebpageTask在你的内部有一个匿名内联类downloadUrl method.

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

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

    //...
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java中将函数作为参数传递 的相关文章

随机推荐

  • Makefiles - ar: *.a: 没有这样的文件或目录....但是有...它就在那里

    尝试编译朋友的代码 但他没有包含 Makefile 我构建了自己的代码 并对我遇到的问题感到困惑 我认为最好将 Makefile 的完整内容发布在下面 我尽量保持简短 CFLAGS Wall pedantic LFLAGS CC gcc R
  • 如何在java中添加一个名为number Of Digits()的新方法?

    我有一个名为 public class ZeroCounter 的程序 我想向其中添加一个名为 numberOfDigits 的新方法 并在 main 方法中添加一行来测试它 我应该怎样去做呢 下面是一小部分代码 public class
  • 使用 cURL PHP 发布到 Facebook 用户的墙

    我正在存储 facebook 用户 ID 和访问令牌 我可以将此信息发布到选定用户的留言墙上吗 在这里找到以下代码 http developers facebook com docs reference api post http deve
  • Xcode 6 Save for Enterprise Deployment 不再为 ipa 创建 plist?

    Xcode 5 帮助为企业 ipa 创建 plist 描述符 Xcode 6 6A313 仅创建 ipa 这是错误还是有意更改 如果是这样 退后一步的原因是什么 如果我之前没有使用 Xcode 5 生成 plist 我需要自己手动构建它 您
  • 如何在 MVC 3 中基于 XML 文件动态创建控件

    我有一个以 XML 格式存储在数据库中的 XML 文件 其中包含一些控件 例如下拉文本框 标签文本区域等 这些控件可能有也可能没有初始值 所以我的目标是读取 XML 文件 并根据控件类型 我需要动态创建该控件并关联初始值 如果有 并且页面的
  • 无法解析的日期:“2013-07-11T13:41:22.000Z”(偏移量 23)

    谁能告诉我为什么我会得到这个例外 08 28 08 47 05 246 D DateParser 4238 接收到的用于解析的字符串是 2013 08 05T12 13 49 000Z private final static String
  • Perl 拆分和正则表达式

    我有以下字符串 100 California Grown Olives Water Salt And Ferrous Gluconate An Iron Derivative asasd sadasda 我想把它分开 but only if
  • 使用 MFC 对象初始化 std::map 无法编译

    MFC初学者看这里 我尝试过初始化std map像这样 在CView的标题中 myprogramView h std map
  • 使用 MVC3 根据 Highchart 条形图中的值更改条形颜色

    我正在使用 Dotnet Highchart 和 MVC3 我目前正在使用一个如下所示的图表 我正在尝试修改我的代码 以便我可以根据条形的数量更改条形的颜色 我还想知道如何删除按钮 Snittbetyg 正如您在图像上看到的那样 这是我的代
  • 如何在 Clang 中检测 libstdc++ 版本?

    我想用 Clang 编写一个 可移植 C 库 可移植 意味着我 在 C 预处理器中 检测编译环境中可用的 C 功能 并使用这些功能或提供我的解决方法 这与 Boost 库所做的类似 然而 某些功能的存在并不取决于语言 而是取决于标准库的实现
  • 我可以在 Electron 应用程序中读取 webview 的 cookie 吗?

    当使用 WebView 元素在 Electron 应用程序中显示其他页面时 是否可以读取和写入其 cookie 是的你可以 通过会话访问cookie const session require electron remote Here we
  • STL列表迭代器不会更新我的对象

    我使用列表迭代器将宠物的所有年龄设置为 1 但更改不会在 for 循环之外持续存在 include
  • 在 python 中创建默认列表

    我正在尝试创建一个非常有用的等效列表collections defaultdict http docs python org library collections html collections defaultdict 下面的设计效果很
  • VB.net 应用程序保留以前的版本

    我有一个正在发布的 Visual Basic 项目 并且每次都会增加版本号 当我安装新版本时 它会打开 但一旦应用程序重新启动 它似乎就会恢复到以前的版本 我不知道为什么 尝试更新发布应用程序时所需的最低版本 转到应用程序属性 gt 发布
  • Meteor的订阅和同步很慢

    我有一个包含 6000 只股票的 10M 文档的集合 股票名称已索引 当我订阅一只新股票时 meteor挂了10多秒 就得到了这只股票的大约3000份文件 同样 在认购了几只股票后 meteor 挂起 CPU 使用率达到 100 Meteo
  • 在没有连接的情况下将 sqlalchemy 核心语句转换为原始 SQL?

    我有一个使用 sqlalchemy 核心的脚本 但不幸的是我需要重写它以使用原始 sql 是否可以在没有显式引擎的情况下将我的 sqla insert etc 语句翻译成特定的方言 这里是 oracle 本质上 能够对 str some s
  • if 子句中的多个条件

    如果我有一个 if 语句需要满足这些要求 if cave gt 0 training gt 0 mobility gt 0 sleep gt 0 有没有办法说它们都大于零 只是为了更高效的 DRY 代码 就像是 if cave traini
  • Swift 无法从上到下呈现视图控制器

    在我的应用程序中 我必须从上到下呈现屏幕 我尝试了下面的代码 它给出了相同的正常呈现风格 let screen self storyboard instantiateViewController withIdentifier Screen1
  • 如何更改 Xamarin.Forms(便携式)应用程序中的 PCL 配置文件

    我只是想知道如何使用 Visual Studio 2015 Update 2 更改 Xamarin 中的 PCL 配置文件 在安装某些软件包时 我收到一条错误消息 该软件包与 PCL 配置文件 259 不兼容 先感谢您 右键单击 PCL 项
  • java中将函数作为参数传递

    我正在熟悉 Android 框架和 Java 并希望创建一个通用的 NetworkHelper 类 该类将处理大部分网络代码 使我能够从中调用网页 我按照developer android com 上的这篇文章创建了我的网络类 http d