Android Code Snippet Pass a reference of a View to a service

Discussion in 'Code Snippets' started by lemonisdead, Jan 22, 2015.

  1. lemonisdead

    lemonisdead Well-Known Member Licensed User

    Hello,

    Following @Informatix's advice, here is a simple way I was not aware of to pass a reference of a view to a service.

    As you already know, Views can only be declared in Globals. So I use a Globals list as a gateway to a wider Process_Globals list that can be retrieved from the service. Like this :

    In the Activity
    Code:
    Sub Process_Globals
        
    'this list is used as a way to pass the View as a Process_Global
        Dim L1 As List
    End Sub

    Sub Globals
        
    'this list is used as a gateway between Globals and Process_Globals
        Dim L As List

        
    Dim mView As Label 'or any other view I think
    End Sub

    Sub Activity_Create(FirstTime As Boolean)

        
    If Not(L.IsInitialized) Then L.Initialize
        
    If Not(L1.IsInitialized) Then L1.Initialize

        
    If FirstTime Then
            mView.Initialize(
    "")
            mView.Text= 
    "Some text"
            L.Add(mView) 
    'stores the view in the gateway
            L1.Add(L.Get(0)) 'stores the view from the gateway to the system wide
        End If

    End Sub
    And in the service where I need the reference to the view :

    Code:
    Sub RemoveOverlay
        
    Dim mView As Label 'same type as the view to retrieve
        mView.Initialize("")
        mView=Main.L1.Get(
    0'gets the reference to the view

    End Sub
    I hope this could help someone who didn't got it (like me) previously
     
    Troberg, raphaelcno and Beja like this.
  2. Informatix

    Informatix Expert Licensed User

    +1 and thank you
    I love these days where I learn new useful things. :)
     
    lemonisdead likes this.
  3. NJDude

    NJDude Expert Licensed User

    Note that your code doesn't work on Lollipop, it crashes if you open an app that alters the status bar, for example:

    1- Open your app and lock the status bar
    2- Open the Google Play app
    3- Exit Google Play
    4- Go back to your app, unlock the status bar
    5- BOOM!

    On my HTC One (KitKat) it crashes all the time I return to your sample and turn the lock off.

    The logs are below.
    Code:
    ** Service (s1) Create **


    ** 
    Service (s1) Start **


    ** 
    Activity (main) Create, isFirst = true **


    ** 
    Activity (main) Resume **


    ** 
    Activity (main) Pause, UserClosed = false **


    ** 
    Activity (main) Create, isFirst = true **


    ** 
    Activity (main) Resume **


    ** 
    Activity (main) Resume **


    ** 
    Activity (main) Pause, UserClosed = true **


    ** 
    Activity (main) Create, isFirst = true **


    ** 
    Activity (main) Resume **


    ** 
    Activity (main) Pause, UserClosed = false **


    ** 
    Activity (listmemes) Create, isFirst = true **


    ** 
    Activity (listmemes) Resume **


    ** 
    Activity (listmemes) Pause, UserClosed = true **


    ** 
    Activity (main) Resume **


    ** 
    Activity (main) Pause, UserClosed = true **


    ** 
    Activity (main) Create, isFirst = false **


    ** 
    Activity (main) Resume **


    java.lang.reflect.InvocationTargetException


        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:
    372)
        at anywheresoftware.b4j.object.JavaObject.RunMethod(
    JavaObject.java:109)
        at b4a.example.s1._addoverlay(s1.java:
    116)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:
    372)
        at anywheresoftware.b4a.BA.raiseEvent2(BA.java:
    175)
        at anywheresoftware.b4a.keywords.Common$
    5.run(Common.java:962)
        at android.os.Handler.handleCallback(Handler.java:
    739)
        at android.os.Handler.dispatchMessage(Handler.java:
    95)
        at android.os.Looper.loop(Looper.java:
    135)
        at android.app.ActivityThread.main(ActivityThread.java:
    5221)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:
    372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:
    899)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:
    694)


    Caused by: java.lang.IllegalStateException: 
    View android.widget.TextView{122390d5 V.ED.... ......I. 0,0-800,100 #3} has already been added to the window manager.
        at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:
    243)
        at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:
    69)
        ... 
    16 more
    java.lang.RuntimeException: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
        at anywheresoftware.b4a.keywords.Common$
    5.run(Common.java:965)
        at android.os.Handler.handleCallback(Handler.java:
    739)
        at android.os.Handler.dispatchMessage(Handler.java:
    95)
        at android.os.Looper.loop(Looper.java:
    135)
        at android.app.ActivityThread.main(ActivityThread.java:
    5221)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:
    372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:
    899)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:
    694)
    Caused by: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
        at anywheresoftware.b4a.BA.raiseEvent2(BA.java:
    201)
        at anywheresoftware.b4a.keywords.Common$
    5.run(Common.java:962)
        ... 
    8 more
    Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:
    372)
        at anywheresoftware.b4j.object.JavaObject.RunMethod(
    JavaObject.java:109)
        at b4a.example.s1._addoverlay(s1.java:
    116)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:
    372)
        at anywheresoftware.b4a.BA.raiseEvent2(BA.java:
    175)
        ... 
    9 more
    Caused by: java.lang.IllegalStateException: 
    View android.widget.TextView{122390d5 V.ED.... ......I. 0,0-800,100 #3} has already been added to the window manager.
        at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:
    243)
        at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:
    69)
        ... 
    16 more
     
  4. lemonisdead

    lemonisdead Well-Known Member Licensed User

    You are right NJDude : I should have stored the overlay status in a Process_Globals variable instead of relaying on the status of the ToggleButton

    The error you get is
    Knowing your high level of development (not kidding), I am sure you understand the way of correcting my error. BTW, it was just an example and sorry for the behavior.
     
    Beja likes this.
  5. Informatix

    Informatix Expert Licensed User

    A Try/Catch around "windowManager.RunMethod(...)" will hide the error if you don't want to bother storing the status (which is not 100% reliable anyway).
     
  6. lemonisdead

    lemonisdead Well-Known Member Licensed User

    I had a rude exchange with a quidam who was not able to make this work and didn't want to beleive that we could update any view from a service.
    After having spent some times with that quidam, I publish the example attached.

    What it does : update the time in a label view directly from a service. It is based on the code example of the post #1 and uses the same technic : use a process global list as a Gateway to your activity's view.

    The example is very simple. There is no magic nor any other update process. Hope this can help
     

    Attached Files:

    Troberg likes this.
  7. Troberg

    Troberg Well-Known Member Licensed User

    I did something similar, by simply declaring a public variable in Process_Globals as Object, and then assign the view to that object. It works, but it has some disadvantages (IntelliSense does not work, you have to use CallSub).
     
    lemonisdead likes this.
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice