openvehicles / Open-Vehicle-Android

Android App for OVMS
Other
55 stars 45 forks source link

Migrate UI to Kotlin #166

Closed francos closed 6 months ago

francos commented 6 months ago

https://github.com/openvehicles/Open-Vehicle-Android/issues/150

francos commented 6 months ago

@dexterbg I have finally finished migrating the rest of the classes to Kotlin. There should be no more Java code in the repo after this merge.

If you find any issues let me know :)

dexterbg commented 6 months ago

First test reveals a null pointer crash when sending a text command from the notifications tab:

FATAL EXCEPTION: main
Process: com.openvehicles.OVMS, PID: 10119
java.lang.NullPointerException: Parameter specified as non-null is null: method com.openvehicles.OVMS.ui.NotificationsFragment.onEditorAction, parameter keyEvent
    at com.openvehicles.OVMS.ui.NotificationsFragment.onEditorAction(Unknown Source:7)
    at android.widget.TextView.onEditorAction(TextView.java:7390)
    at com.android.internal.inputmethod.EditableInputConnection.performEditorAction(EditableInputConnection.java:156)
    at android.view.inputmethod.InputConnectionWrapper.performEditorAction(InputConnectionWrapper.java:246)
    at com.android.internal.inputmethod.RemoteInputConnectionImpl.lambda$performEditorAction$21$com-android-internal-inputmethod-RemoteInputConnectionImpl(RemoteInputConnectionImpl.java:654)
    at com.android.internal.inputmethod.RemoteInputConnectionImpl$$ExternalSyntheticLambda33.run(Unknown Source:6)
    at android.os.Handler.handleCallback(Handler.java:942)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loopOnce(Looper.java:201)
    at android.os.Looper.loop(Looper.java:288)
    at android.app.ActivityThread.main(ActivityThread.java:7946)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:569)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1019)

Apparently, this only happens when entering commands manually, running stored commands works.

dexterbg commented 6 months ago

The App also crashes on selecting any menu entry on the maps tab.

java.lang.IndexOutOfBoundsException: Index 572 out of bounds for length 572
    at jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
    at jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)
    at jdk.internal.util.Preconditions.checkIndex(Preconditions.java:266)
    at java.util.Objects.checkIndex(Objects.java:359)
    at java.util.ArrayList.get(ArrayList.java:434)
    at com.openvehicles.OVMS.ui.MapFragment.updateMapDetails(MapFragment.kt:351)
    at com.openvehicles.OVMS.ui.MapFragment.onOptionsItemSelected(MapFragment.kt:279)
    at androidx.fragment.app.Fragment.performOptionsItemSelected(Fragment.java:3122)
    at androidx.fragment.app.FragmentManager.dispatchOptionsItemSelected(FragmentManager.java:3226)
    at androidx.fragment.app.FragmentController.dispatchOptionsItemSelected(FragmentController.java:416)
    at androidx.fragment.app.FragmentActivity.onMenuItemSelected(FragmentActivity.java:358)
    at androidx.appcompat.app.AppCompatActivity.onMenuItemSelected(AppCompatActivity.java:269)
    at androidx.appcompat.view.WindowCallbackWrapper.onMenuItemSelected(WindowCallbackWrapper.java:110)
    at androidx.appcompat.app.AppCompatDelegateImpl.onMenuItemSelected(AppCompatDelegateImpl.java:1259)
    at androidx.appcompat.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:836)
    at androidx.appcompat.view.menu.SubMenuBuilder.dispatchMenuItemSelected(SubMenuBuilder.java:91)
    at androidx.appcompat.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:159)
    at androidx.appcompat.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:987)
    at androidx.appcompat.view.menu.MenuPopup.onItemClick(MenuPopup.java:128)
    at android.widget.AdapterView.performItemClick(AdapterView.java:330)
    at android.widget.AbsListView.performItemClick(AbsListView.java:1197)
    at android.widget.AbsListView$PerformClick.run(AbsListView.java:3210)
    at android.widget.AbsListView.onTouchUp(AbsListView.java:4188)
    at android.widget.AbsListView.onTouchEvent(AbsListView.java:3929)
    at androidx.appcompat.widget.DropDownListView.onTouchEvent(DropDownListView.java:236)
    at androidx.appcompat.widget.MenuPopupWindow$MenuDropDownListView.onTouchEvent(MenuPopupWindow.java:140)
    at android.view.View.dispatchTouchEvent(View.java:15057)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3168)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2810)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3174)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2824)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3174)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2824)
    at android.widget.PopupWindow$PopupDecorView.dispatchTouchEvent(PopupWindow.java:2597)
    at android.view.View.dispatchPointerEvent(View.java:15321)
    at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:6842)
    at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:6623)
    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:6075)
    at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:6132)
    at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:6098)
    at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:6263)
    at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:6106)
    at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:6320)
    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:6079)
    at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:6132)
    at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:6098)
    at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:6106)
    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:6079)
    at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:9233)
    at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:9184)
dexterbg commented 6 months ago

At least some vehicle specific menus are missing, i.e. when switching to a Twizy, the battery tab no longer shows the battery cell & energy chart menus.

francos commented 6 months ago

Hi @dexterbg just saw your messages, I noticed you merged the PR anyway, does it mean you fixed the issues already?

dexterbg commented 6 months ago

No, not fixed yet. I probably should have tested your PR before, but assumed no issues as with your previous rework part.

I didn't update the latest build yet, assuming the issues can be solved quickly.

dexterbg commented 5 months ago

Franco, the PR fixed the command crash and selecting the checkbox entries of the map menu now works. Selecting the map configuration from the menu still crashes the App:

FATAL EXCEPTION: main
Process: com.openvehicles.OVMS, PID: 10335
java.lang.IllegalStateException: Fragment MapSettingsFragment{13b9662} (4dadf7f4-270d-4f67-850c-d4becf9cdda0 id=0x7f0900a5) did not return a View from onCreateView() or this was called before onCreateView().
    at androidx.fragment.app.Fragment.requireView(Fragment.java:1964)
    at com.openvehicles.OVMS.ui.MapSettingsFragment.setUpClusteringViews(MapSettingsFragment.kt:43)
    at com.openvehicles.OVMS.ui.MapSettingsFragment.onCreateView(MapSettingsFragment.kt:34)
    at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2963)
    at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:518)
    at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:282)
    at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2189)
    at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:2100)
    at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:2002)
    at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3138)
    at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:3072)
    at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:251)
    at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:502)
    at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:251)
    at com.openvehicles.OVMS.ui.ApiActivity.onStart(ApiActivity.kt:67)
    at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1543)
    at android.app.Activity.performStart(Activity.java:8330)
    at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3670)
    at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221)
    at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201)
    at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173)
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2307)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loopOnce(Looper.java:201)
    at android.os.Looper.loop(Looper.java:288)
    at android.app.ActivityThread.main(ActivityThread.java:7872)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)

Also, on restarting the App after a crash, I see this crash in the log:

FATAL EXCEPTION: main
Process: com.openvehicles.OVMS, PID: 10272
java.lang.RuntimeException: Unable to start service com.openvehicles.OVMS.api.ApiService@81596e3 with null: java.lang.NullPointerException: Parameter specified as non-null is null: method com.openvehicles.OVMS.api.ApiService.onStartCommand, parameter intent
    at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:4673)
    at android.app.ActivityThread.-$$Nest$mhandleServiceArgs(Unknown Source:0)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2180)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loopOnce(Looper.java:201)
    at android.os.Looper.loop(Looper.java:288)
    at android.app.ActivityThread.main(ActivityThread.java:7872)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
Caused by: java.lang.NullPointerException: Parameter specified as non-null is null: method com.openvehicles.OVMS.api.ApiService.onStartCommand, parameter intent
    at com.openvehicles.OVMS.api.ApiService.onStartCommand(Unknown Source:2)
    at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:4655)
    at android.app.ActivityThread.-$$Nest$mhandleServiceArgs(Unknown Source:0) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2180) 
    at android.os.Handler.dispatchMessage(Handler.java:106) 
    at android.os.Looper.loopOnce(Looper.java:201) 
    at android.os.Looper.loop(Looper.java:288) 
    at android.app.ActivityThread.main(ActivityThread.java:7872) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936) 

Regarding the Twizy issues, you need a module configured for vehicle type Twizy and the App needs to have a Twizy image selected for the vehicle to see the additional feature menus. The menus are now visible, but also lead to crashes, for example when opening the Twizy BMS view, I get:

FATAL EXCEPTION: main
Process: com.openvehicles.OVMS, PID: 10548
kotlin.UninitializedPropertyAccessException: lateinit property cellChart has not been initialized
    at com.openvehicles.OVMS.ui.BatteryFragment.onCreateView(BatteryFragment.kt:113)
    at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2963)
    at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:518)
    at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:282)
    at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2189)
    at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:2100)
    at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:2002)
    at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3138)
    at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:3072)
    at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:251)
    at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:502)
    at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:251)
    at com.openvehicles.OVMS.ui.ApiActivity.onStart(ApiActivity.kt:67)
    at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1543)
    at android.app.Activity.performStart(Activity.java:8330)
    at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3670)
    at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221)
    at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201)
    at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173)
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2307)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loopOnce(Looper.java:201)
    at android.os.Looper.loop(Looper.java:288)
    at android.app.ActivityThread.main(ActivityThread.java:7872)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)

I'll try to recreate some Twizy specific data to be able to test the power/energy chart.

Regards, Michael