Android App / Java开发新手,解决了一些异常问题

时间:2016-09-21 10:01:06

标签: java android android-studio

正如标题所说,我刚刚开始编写Android智能手机应用程序,这也是我第一次用Java编写。我确实有一些 C / C ++ / Swift / iOS 应用程序开发的经验。

我一直在看教程,我已经设法让一些基本的东西与按钮一起工作,但有一些我想改变的异常。对于初学者来说,似乎只允许我声明按钮变量并在我的onCreate()方法的范围内使用它们,如下所示。

main activity

如果我尝试将所有内容移到public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final boolean[] connect_btn_pressed = {false}; final ImageButton btn_up = (ImageButton) findViewById(R.id.btn_up); final ImageButton btn_connect = (ImageButton) findViewById(R.id.btn_connect); final TextView ble_status = (TextView) findViewById(R.id.bt_message); btn_up.setVisibility(View.INVISIBLE); btn_connect.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if(connect_btn_pressed[0] == false){ ble_status.setText("Connecting..."); btn_connect.setImageResource(R.drawable.btn_x1_bt_on); btn_up.setVisibility(View.VISIBLE); connect_btn_pressed[0] = true; } else { ble_status.setText("Cancelled"); btn_connect.setImageResource(R.drawable.btn_x1_bt_off); btn_up.setVisibility(View.INVISIBLE); connect_btn_pressed[0] = false; } } }); } 方法之外,我就无法使用onCreate()调用,因为btn_up.setVisibility(View.INVISIBLE)参数存在问题。

我找到了关键字View.INVISIBLE,我不确定为什么这是必要的。

最后,只要我尝试在final方法中引用它,我的boolean变量也会变为array并且只有一个元素。如果它确实是必要的话,我会让它滑动,但它仍然让我觉得我不能只使用它一个简单的布尔元素。

那么如何将这些代码行移到onClick()范围之外呢?我想在onCreate()方法中引用这些按钮,但在当前状态下无法访问它们。

为什么我的变量需要声明onPause()?我是否真的需要将final标记声明为boolean

编辑:

现在我的代码设置如下:

array

它构建并运行但是现在一旦活动启动,我的应用程序崩溃了。这是我的堆栈跟踪:

public class MainActivity extends AppCompatActivity {

    boolean connect_btn_pressed = false;

    ImageButton btn_up = (ImageButton) findViewById(R.id.btn_up);
    ImageButton btn_down = (ImageButton) findViewById(R.id.btn_down);
    ImageButton btn_right = (ImageButton) findViewById(R.id.btn_right);
    ImageButton btn_left = (ImageButton) findViewById(R.id.btn_left);
    ImageButton btn_connect = (ImageButton) findViewById(R.id.btn_connect);
    TextView ble_status = (TextView) findViewById(R.id.bt_message);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btn_up.setVisibility(View.INVISIBLE);
        btn_down.setVisibility(View.INVISIBLE);
        btn_right.setVisibility(View.INVISIBLE);
        btn_left.setVisibility(View.INVISIBLE);

        btn_connect.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(!connect_btn_pressed){
                    ble_status.setText(R.string.bt_statusmessage_connecting);
                    btn_connect.setImageResource(R.drawable.btn_x1_bt_on);
                    btn_up.setVisibility(View.VISIBLE);
                    btn_down.setVisibility(View.VISIBLE);
                    btn_left.setVisibility(View.VISIBLE);
                    btn_right.setVisibility(View.VISIBLE);
                    connect_btn_pressed = true;
                }
                else {
                    ble_status.setText(R.string.bt_statusmessage_cancelled);
                    btn_connect.setImageResource(R.drawable.btn_x1_bt_off);
                    btn_up.setVisibility(View.INVISIBLE);
                    btn_down.setVisibility(View.INVISIBLE);
                    btn_left.setVisibility(View.INVISIBLE);
                    btn_right.setVisibility(View.INVISIBLE);
                    connect_btn_pressed = false;
                }
            }
        });

    }




    /*btn_left.setOnTouchListener(new OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            return false;
        }
    });*/

    /* Called when the user clicks the Send button */
    public void sendMessage(View view) {
        //
    }

}

当我还原更改时,应用运行正常。

解决:

崩溃的原因是因为我在尝试使用findViewById之前尝试设置声明的变量。我通过将声明保持在09/21 14:00:23: Launching app Cold swapped changes. $ adb shell am start -n "com.rcbot/com.rcbot.Splash" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER Connected to process 13828 on device samsung-sm_g930p-91daafa6 E/Zygote: v2 W/SELinux: Function: selinux_compare_spd_ram, index[1], priority [2], priority version is VE=SEPF_SECMOBILE_6.0.1_0012 E/Zygote: accessInfo : 0 W/SELinux: SELinux: seapp_context_lookup: seinfo=default, level=s0:c512,c768, pkgname=com.rcbot I/art: Late-enabling -Xcheck:jni I/libpersona: KNOX_SDCARD checking this for 10214 I/libpersona: KNOX_SDCARD not a persona D/TimaKeyStoreProvider: TimaSignature is unavailable D/ActivityThread: Added TimaKeyStore provider I/InjectionManager: Inside getClassLibPath + mLibMap{0=, 1=} I/InjectionManager: Inside getClassLibPath caller W/ResourcesManager: getTopLevelResources: /data/app/com.rcbot-2/base.apk / 1.0 running in com.rcbot rsrc of package com.rcbot D/ResourcesManager: For user 0 new overlays fetched Null W/System: ClassLoader referenced unknown path: /data/app/com.rcbot-2/lib/arm64 I/InstantRun: Instant Run Runtime started. Android package is com.rcbot, real application class is null. W/System: ClassLoader referenced unknown path: /data/app/com.rcbot-2/lib/arm64 D/InjectionManager: InjectionManager D/InjectionManager: fillFeatureStoreMap com.rcbot I/InjectionManager: Constructor com.rcbot, Feature store :{} I/InjectionManager: featureStore :{} W/ResourcesManager: getTopLevelResources: /data/data/com.rcbot/files/instant-run/right/resources.ap_ / 1.0 running in com.rcbot rsrc of package com.rcbot D/ResourcesManager: For user 0 new overlays fetched Null D/RelationGraph: garbageCollect() D/ContextRelationManager: ContextRelationManager() : FEATURE_ENABLED=true W/ResourcesManager: getTopLevelResources: /data/app/com.rcbot-2/base.apk / 1.0 running in com.rcbot rsrc of package com.rcbot W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable D/Activity: performCreate Call Injection manager I/InjectionManager: dispatchOnViewCreated > Target : com.rcbot.Splash isFragment :false D/ViewRootImpl: #1 mView = com.android.internal.policy.PhoneWindow$DecorView{705cd69 I.E...... R.....ID 0,0-0,0} D/OpenGLRenderer: Use EGL_SWAP_BEHAVIOR_PRESERVED: true D/SecWifiDisplayUtil: Metadata value : SecSettings2 I/Adreno: QUALCOMM build : f3dae48, Ic65b418ec7 Build Date : 04/08/16 OpenGL ES Shader Compiler Version: XE031.06.00.05 Local Branch : Remote Branch : refs/tags/AU_LINUX_ANDROID_LA.HB.1.1.1.C1.06.00.00.165.137 Remote Branch : NONE Reconstruct Branch : NOTHING D/libEGL: eglInitialize EGLDisplay = 0x7f64a3a188 I/OpenGLRenderer: Initialized EGL, version 1.4 I/InjectionManager: dispatchCreateOptionsMenu :com.rcbot.Splash I/InjectionManager: dispatchPrepareOptionsMenu :com.rcbot.Splash D/ViewRootImpl: MSG_RESIZED_REPORT: ci=Rect(0, 96 - 0, 0) vi=Rect(0, 96 - 0, 0) or=1 D/libGLESv1: DTS_GLAPI : DTS is not allowed for Package : com.rcbot I/Timeline: Timeline: Activity_idle id: android.os.BinderProxy@da565f2 time:125966383 D/AndroidRuntime: Shutting down VM E/AndroidRuntime: FATAL EXCEPTION: main Process: com.rcbot, PID: 13828 java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.rcbot/com.rcbot.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.Window$Callback android.view.Window.getCallback()' on a null object reference at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3093) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3349) at android.app.ActivityThread.access$1100(ActivityThread.java:221) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1794) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:158) at android.app.ActivityThread.main(ActivityThread.java:7224) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120) Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.Window$Callback android.view.Window.getCallback()' on a null object reference at android.support.v7.app.AppCompatDelegateImplBase.<init>(AppCompatDelegateImplBase.java:116) at android.support.v7.app.AppCompatDelegateImplV9.<init>(AppCompatDelegateImplV9.java:147) at android.support.v7.app.AppCompatDelegateImplV11.<init>(AppCompatDelegateImplV11.java:27) at android.support.v7.app.AppCompatDelegateImplV14.<init>(AppCompatDelegateImplV14.java:50) at android.support.v7.app.AppCompatDelegateImplV23.<init>(AppCompatDelegateImplV23.java:29) at android.support.v7.app.AppCompatDelegate.create(AppCompatDelegate.java:199) at android.support.v7.app.AppCompatDelegate.create(AppCompatDelegate.java:181) at android.support.v7.app.AppCompatActivity.getDelegate(AppCompatActivity.java:521) at android.support.v7.app.AppCompatActivity.findViewById(AppCompatActivity.java:190) at com.rcbot.MainActivity.<init>(MainActivity.java:24) at java.lang.Class.newInstance(Native Method) at android.app.Instrumentation.newActivity(Instrumentation.java:1095) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3083) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3349)  at android.app.ActivityThread.access$1100(ActivityThread.java:221)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1794)  at android.os.Handler.dispatchMessage(Handler.java:102)  at android.os.Looper.loop(Looper.java:158)  at android.app.ActivityThread.main(ActivityThread.java:7224)  at java.lang.reflect.Method.invoke(Native Method)  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)  之上,然后将赋值移动到其中的变量来修复它。

4 个答案:

答案 0 :(得分:0)

您的代码已更正:

public class MainActivity extends AppCompatActivity {

private boolean connect_btn_pressed = false;

private ImageButton btn_up;
private ImageButton btn_connect;
private TextView ble_status;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    connect_btn_pressed = false;

    btn_up = (ImageButton) findViewById(R.id.btn_up);
    btn_connect = (ImageButton) findViewById(R.id.btn_connect);
    ble_status = (TextView) findViewById(R.id.bt_message);

    btn_up.setVisibility(View.INVISIBLE);

    btn_connect.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (connect_btn_pressed == false) {
                ble_status.setText("Connecting...");
                btn_connect.setImageResource(R.drawable.btn_x1_bt_on);
                btn_up.setVisibility(View.VISIBLE);
                connect_btn_pressed = true;
            } else {
                ble_status.setText("Cancelled");
                btn_connect.setImageResource(R.drawable.btn_x1_bt_off);
                btn_up.setVisibility(View.INVISIBLE);
                connect_btn_pressed = false;
            }
        }
    });
}
}

1)最后,在你的方法中,由于范围是必要的。不是类变量,它的作用域是方法,因此OnClickListener内部不是&#34;可查看&#34;。

2)通过在新范围内获取变量,我对View参数没有任何问题。我不确定你为什么需要这样做。

3)现在你的变量可以用在onPause()方法中,解释是一样的:它们超出了范围。

答案 1 :(得分:0)

做一些像这样的改变

public class MainActivity extends AppCompatActivity {
boolean[] connect_btn_pressed ;
ImageButton btn_up,btn_connect ;
TextView ble_status;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        connect_btn_pressed = {false};

        btn_up = (ImageButton) findViewById(R.id.btn_up);
        btn_connect = (ImageButton) findViewById(R.id.btn_connect);
        ble_status = (TextView) findViewById(R.id.bt_message);

        btn_up.setVisibility(View.INVISIBLE);

        btn_connect.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if(connect_btn_pressed[0] == false){
                    ble_status.setText("Connecting...");
                    btn_connect.setImageResource(R.drawable.btn_x1_bt_on);
                    btn_up.setVisibility(View.VISIBLE);
                    connect_btn_pressed[0] = true;
                }
                else {
                    ble_status.setText("Cancelled");
                    btn_connect.setImageResource(R.drawable.btn_x1_bt_off);
                    btn_up.setVisibility(View.INVISIBLE);
                    connect_btn_pressed[0] = false;
            }
        }
    });
}

答案 2 :(得分:0)

欢迎来到marco家庭!

尝试在reference方法之外声明onCreate()变量!那就是你不应该将它声明为onCreate()方法的本地!

只有这样您才能访问btn_up.setVisiblity()。如果这样做,final的隐式发生也将被消除。

答案 3 :(得分:0)

你可以在onCreate之外声明ImageButton btn_up,并在onCreate中初始化它,这样你就可以在onPause中访问它:

ImageButton btn_up;

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

btn_up = (ImageButton) findViewById(R.id.btn_up);
btn_up.setVisibility(View.INVISIBLE);

}

关于布尔变量 - 当你添加[]时,你将它声明为一个数组...你可以用同样的方式做到:

外面的onCreate: boolean connect_btn_pressed; //默认值为false

然后在onClick上:

if(!connect_btn_pressed){ //if connect_btn_pressed is false

}