Java Android中的“无法对非静态方法进行静态引用”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2218773/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 04:50:56  来源:igfitidea点击:

"Cannot make a static reference to a non-static method" in Android

javaandroidstatic

提问by gkanwar

I'm having some issues with the old "Cannot make a static reference to a non-static method" error in my Android program. I am creating a sand falling game (similar to the Powder Game) and I created a class called Control to create a Control Bar at the bottom of the screen with a slider for brush size (that works fine) and a button to pop up a Dialog to allow users to pick the selected element. However, when I call DemoActivity.showDialog(2) from my code, it gives the static reference to non-static error (DemoActivity is the main activity of my application). I also tried changing it to just Activity.showDialog(2), but I got exactly the same error! Please help, what am I doing wrong? Here's my code and thanks in advance:

我在我的 Android 程序中遇到了旧的“无法对非静态方法进行静态引用”错误的一些问题。我正在创建一个落沙游戏(类似于粉末游戏),我创建了一个名为 Control 的类,以在屏幕底部创建一个控制栏,并带有一个用于画笔大小的滑块(工作正常)和一个按钮来弹出一个允许用户选择所选元素的对话框。但是,当我从代码中调用 DemoActivity.showDialog(2) 时,它给出了对非静态错误的静态引用(DemoActivity 是我的应用程序的主要活动)。我也尝试将其更改为 Activity.showDialog(2),但我得到了完全相同的错误!请帮忙,我做错了什么?这是我的代码,并提前致谢:

package sand.falling.opengl;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.SeekBar;

public class Control extends LinearLayout
{
    private ImageButton control_button;
    private SeekBar brush_size_slider;

    final CharSequence[] elementslist = {"Sand", "Water", "Plant", "Wall", "Fire", "Ice", "Generator", "Oil", "Magma", "Stone", "C4"};

    public Control(Context context, AttributeSet attrs)
    {
        super(context, attrs);
    }

    @Override
    protected void onFinishInflate()
    {
        control_button = (ImageButton) findViewById(R.id.element_picker_button);
        brush_size_slider = (SeekBar) findViewById(R.id.brush_size_slider);

        control_button.setOnClickListener
            (
                    new OnClickListener()
                    {
                        public void onClick(View v)
                        {
                            //THIS DOESN'T WORK!!!!
                            DemoActivity.showDialog(2); //Run the element picker dialog
                        }
                    }
            );
        control_button.setImageResource(R.drawable.palette);

        brush_size_slider.setOnSeekBarChangeListener
            (
                    new SeekBar.OnSeekBarChangeListener()
                    {
                        public void onProgressChanged(SeekBar seekbar, int progress, boolean fromTouch)
                        {
                            int p = 32 * progress/100;
                            DemoActivity.setBrushSize(p);
                            Log.v("DemoActivity", "size:" + p);
                        }
                        public void onStartTrackingTouch(SeekBar seekbar) {}
                        public void onStopTrackingTouch(SeekBar seekbar) {}
                    }
            );
        brush_size_slider.setProgress((int)400/32);
    }
}

EDIT: I fixed it by adding the following to my Control.java code:

编辑:我通过将以下内容添加到我的 Control.java 代码中来修复它:

public class Control extends LinearLayout
{
    private DemoActivity activity;
        ...
    public void setActivity(DemoActivity act)
    {
        activity = act;
    }
        ...
        //Set a click listener for the button which should pop up element picker dialog when clicked
        control_button.setOnClickListener
            (
                    new OnClickListener()
                    {
                        public void onClick(View v)
                        {
                            activity.showDialog(2); //Run the element picker dialog
                        }
                    }
            );
}

And then calling control.setActivity(this);from my onResume section of DemoActivity.java! Hope it helps those of you with similar issues!!

然后control.setActivity(this);从我的 DemoActivity.java 的 onResume 部分调用!希望能帮到有类似问题的小伙伴!!

采纳答案by Kaleb Brasee

You have to call showDialogon a DemoActivityinstance, NOT on the class itself. The only time you can call ClassName.methodName()is if the method is defined as static. showDialogis not a static method.

你必须调用showDialog一个DemoActivity实例,而不是类本身。您可以调用的唯一时间ClassName.methodName()是将方法定义为静态。 showDialog不是静态方法。

To fix this, you either need to instantiate a new DemoActivityor get an existing one, then call showDialogon that.

要解决此问题,您需要实例化一个新实例DemoActivity或获取现有实例,然后调用showDialog它。

Edit:If you already have a DemoActivityinstance when you instantiate this Controlobject, perhaps the following modification will work:

编辑:如果你在DemoActivity实例化这个Control对象时已经有一个实例,也许下面的修改会起作用:

public class Control extends LinearLayout
{

    ...

    // add an Activity instance
    private Activity activity;

    // set the Activity in your constructor
    public Control(Context context, AttributeSet attrs, Activity activity)
    {
        super(context, attrs);
        this.activity = activity;
    }

    @Override
    protected void onFinishInflate()
    {
        ...

           // Use the instance activity here
           activity.showDialog(2);
        ...
    }
}

回答by JDPearlman

if the create is called by ANDROID, so you do not create the instance, just put into the create mShowDialog=thisor mShowDialog=pShowDialog

如果 create 被 ANDROID 调用,那么你不创建实例,只需放入 createmShowDialog=thismShowDialog=pShowDialog

in other words - have the create save the instance value also you can add a public get to get that instance value. Then you can access the instance function through the abstract by interceding the getter:

换句话说 - 让 create 保存实例值,您也可以添加一个公共 get 来获取该实例值。然后你可以通过调用getter来通过抽象访问实例函数:

ABSTRACTCLASS.getInstance().applyFunction();