簡體   English   中英

為了清楚起見,如何將MainActivity功能拆分為另一個類?

[英]How can I split MainActivity functionality into an another class for clarity?

我有一個android程序,我希望能夠將MainActivity中的功能拆分為多個文件以保持代碼井井有條,但是我收到了空對象引用錯誤。

為了演示該錯誤,我創建了一個簡單的程序,該程序只有一個textView和一個用於更改textView的按鈕。 單擊按鈕時發生錯誤。 如何解決此問題,以便可以參加幫助課程?

MainActivity.java

package com.example.testapp;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;

public class MainActivity extends AppCompatActivity {
    private MainActivityHelper mainActivityHelper;

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

        mainActivityHelper = new MainActivityHelper();
    }

    public void buttonPressed(View view) {
        mainActivityHelper.changeText();
    }
}

MainActivityHelper.java

package com.example.testapp;

import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivityHelper extends AppCompatActivity {
    public MainActivityHelper() {

    }

    public void changeText() {
        TextView textView = findViewById(R.id.helloString);

        if(textView.getText().toString() == "Hello World!") {
            textView.setText("Goodbye world!");
        }
        else {
            textView.setText("Hello World!");
        }
    }
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.testapp">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

錯誤信息:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.testapp, PID: 17322
    java.lang.IllegalStateException: Could not execute method for android:onClick
        at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:389)
        at android.view.View.performClick(View.java:6294)
        at android.view.View$PerformClick.run(View.java:24770)
        at android.os.Handler.handleCallback(Handler.java:790)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6494)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
     Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Method.invoke(Native Method)
        at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:384)
        at android.view.View.performClick(View.java:6294) 
        at android.view.View$PerformClick.run(View.java:24770) 
        at android.os.Handler.handleCallback(Handler.java:790) 
        at android.os.Handler.dispatchMessage(Handler.java:99) 
        at android.os.Looper.loop(Looper.java:164) 
        at android.app.ActivityThread.main(ActivityThread.java:6494) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807) 
     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:117)
        at android.support.v7.app.AppCompatDelegateImplV9.<init>(AppCompatDelegateImplV9.java:149)
        at android.support.v7.app.AppCompatDelegateImplV14.<init>(AppCompatDelegateImplV14.java:56)
        at android.support.v7.app.AppCompatDelegateImplV23.<init>(AppCompatDelegateImplV23.java:31)
        at android.support.v7.app.AppCompatDelegateImplN.<init>(AppCompatDelegateImplN.java:31)
        at android.support.v7.app.AppCompatDelegate.create(AppCompatDelegate.java:198)
        at android.support.v7.app.AppCompatDelegate.create(AppCompatDelegate.java:183)
        at android.support.v7.app.AppCompatActivity.getDelegate(AppCompatActivity.java:519)
        at android.support.v7.app.AppCompatActivity.findViewById(AppCompatActivity.java:190)
        at com.example.testapp.MainActivityHelper.changeText(MainActivityHelper.java:14)
        at com.example.testapp.MainActivity.buttonPressed(MainActivity.java:19)
        at java.lang.reflect.Method.invoke(Native Method) 
        at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:384) 
        at android.view.View.performClick(View.java:6294) 
        at android.view.View$PerformClick.run(View.java:24770) 
        at android.os.Handler.handleCallback(Handler.java:790) 
        at android.os.Handler.dispatchMessage(Handler.java:99) 
        at android.os.Looper.loop(Looper.java:164) 
        at android.app.ActivityThread.main(ActivityThread.java:6494) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807) 

您有一個空指針,因為尚未設置Main活動助手的內容視圖。 在另一個對象中使用和活動不是實現目標的正確方法。

如果您想擁有一個助手類,則不必擴展一個Activity或聲明一個為Activity的字段。 最好的方法是使用一個視圖模型,該視圖模型是mvvm模式中常用的后端類。 視圖模型允許將邏輯與活動代碼分離。

如果要繼續下去,只需聲明一個普通的Java類,然后將Activity的引用傳遞給該類的構造函數。 在主活動的onCreate中類似以下內容:

MainActivityHelper =新的MainActivityHelper(this);

之后,您可以在助手中調用您的活動方法(例如,喜歡findviewbyid)。

希望這會給您一些提示/幫助。

干杯。

您不能只是這樣破壞活動。 我建議在活動內部使用片段,這樣您就可以用特定的代碼段隔離每個片段,並只需簡單地調用活動即可(此時,活動是粘貼所有片段的簡單容器,用作調解員)。

請看一下這個Android Fragments

這可能已經過時了,但這是一個很好的切入點

您不能將活動分為擴展AppCompatActivity類的兩個類,但是可以有一個輔助程序類或“ Utils”類,其中包含一組靜態函數,每個靜態函數都用於特定目的。 這樣,您可以通過最小化活動代碼並將部分代碼移到幫助程序類中,使活動代碼更具可讀性。

另外,您可以將ViewModel與LiveData一起使用以分離數據“獲取”邏輯和UI邏輯。 您可以在此處了解更多信息: https : //developer.android.com/jetpack/docs/guide

您將獲得NPE ,因為您使用的是findViewById而不附加內容視圖。

您可以創建一個單獨的類,然后將此方法和所有其他方法放入其中:

包含所有常量的類

public final class Constants {

    public static final String HELLO_WORLD = "Hello World!";
    public static final String GOODBYE_WORLD = "Goodbye world!";

}

包含所有方法的類

public class Methods {

    public static void changeText(TextView textView) {
        if(textView.getText().toString() == Constants.HELLO_WORLD) {
            textView.setText(Constants.GOODBYE_WORLD);
        }
        else {
            textView.setText(Constants.HELLO_WORLD);
        }
    }


    public static void otherMethods() {
        // other methods
    }


}

並像這樣在您的MainActivity使用它

setContentView(R.layout.activity_main);

TextView textView = findViewById(R.id.helloString);
Methods.changeText(textView)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM