0

Till I added the below lines for Urlrequest, my kivy app worked on my android and opened instantly with the right output . Now after adding the urlrequest code, I have a never ending black screen on my android. Why is this happening? My laptop though shows the right output. Please help me with a fix. Still waiting for a solution!


    from kivy.network.urlrequest import UrlRequest
    
    def where(): 
        f = os.path.dirname(file) 
        return os.path.join(f, 'cacert.pem') 
    
    req = UrlRequest(scan_url, req_body=jdata, ca_file=where(), verify= True)
    req.wait()
    resp = req.result
    indicator_values = resp["data"][0]['d']
    ```
      
    class TA_Handler(BoxLayout):
        screener = ""
        exchange = ""
        symbol = ""
        interval = "1d"
    
        #Get analysis
        def on_getCloudEvents_success(self,request,result):
            print("on_getCloudEvents_success called:")
            print("  result="+str(result))
            self.resp = result
            self.SYNC_REQUEST_STAT="Success" # to end the synchronous wait
            
            
        def on_getCloudEvents_failure(self,request,result):
            print("on_getCloudEvents_failure called:")
            print("  request was sent to "+str(request.url))
            print("    request body="+str(request.req_body))
            print("    request headers="+str(request.req_headers))
            print("  result="+str(request.result))
            self.SYNC_REQUEST_STAT="Failure" # to end the synchronous wait
    
        def on_getCloudEvents_error(self,request,result):
            print("on_getCloudEvents_error called:")
            print("  request was sent to "+str(request.url))
            print("    request body="+str(request.req_body))
            print("    request headers="+str(request.req_headers))
            print("  result="+str(request.result))        
            self.SYNC_REQUEST_STAT="Error" # to end the synchronous wait
            
            
        def get_analysis(self):
            super(TA_Handler,self).__init__()
            """Get analysis from TradingView and compute it.
    
            Returns:
                Analysis: Contains information about the analysis.
            """
            if self.screener == "" or type(self.screener) != str:
                raise Exception("Error: screener is empty or not valid")
            elif self.exchange == "" or type(self.exchange) != str:
                raise Exception("Error: exchange is empty or not valid")
            elif self.symbol == "" or type(self.symbol) != str:
                raise Exception("Error: symbol is empty or not valid")
            elif self.interval == "" or type(self.symbol) != str:
                warnings.warn("Warning: interval is empty or not valid, defaulting to 1 day.")
    
            exch_smbl = self.exchange.upper() + ":" + self.symbol.upper()
            data = TradingView.data(exch_smbl, self.interval)
            scan_url = TradingView.scan_url + self.screener.lower() + "/scan"
            self.resp = None
    
            jdata = json.dumps(data).encode('utf-8')          
            request = UrlRequest(scan_url, req_body=jdata,ca_file=where(),verify=True,\
                on_success=self.on_getCloudEvents_success,
                on_failure=self.on_getCloudEvents_failure,
                on_error=self.on_getCloudEvents_error)
    
    #
            resp=request.result
            indicator_values = resp["data"][0]['d']  
            
    
            oscillators_counter, ma_counter = {"BUY": 0, "SELL": 0, "NEUTRAL": 0}, {"BUY": 0, "SELL": 0, "NEUTRAL": 0}
            computed_oscillators, computed_ma = {}, {}
    
            # RECOMMENDATIONS
            recommend_oscillators = Compute.Recommend(indicator_values[0])
            recommend_summary = Compute.Recommend(indicator_values[1])
            recommend_moving_averages = Compute.Recommend(indicator_values[2])
    
            # OSCILLATORS
            # RSI (14)
            # some code
            analysis.summary = {"RECOMMENDATION": recommend_summary, "BUY": oscillators_counter["BUY"] + ma_counter["BUY"], "SELL": oscillators_counter["SELL"] + ma_counter["SELL"], "NEUTRAL": oscillators_counter["NEUTRAL"] + ma_counter["NEUTRAL"]}
            return analysis
    
    class MainApp(App):
        def this_job(self):
        
            handler = TA_Handler()
            handler.symbol = "BTCUSDT"
            
            handler.exchange = "BITTREX"
            handler.screener = "crypto"
            osc=[]
            ma=[]
            sum1=[]
            for h in ['15m','1h','4h','1d','1W']:
                handler.interval = h # 1 day
                analysis = handler.get_analysis()
                osc1_rec = (analysis.oscillators).get('RECOMMENDATION')
                sum_rec = (analysis.summary).get('RECOMMENDATION')
                ma_rec = (analysis.moving_averages).get('RECOMMENDATION')
                osc.append(osc1_rec)
                ma.append(ma_rec)
                sum1.append(sum_rec)
            return osc,ma, sum1
    
    
        def build(self):
    #        osc=[]
    #        ma=[]
    #        sum1=[]
            handler = TA_Handler()
            handler.symbol = "BTCUSDT"
            
            handler.exchange = "BITTREX"
            handler.screener = "crypto"
            osc=[]
            ma=[]
            sum1=[]
            for h in ['15m','1h','4h','1d','1W']:
                handler.interval = h # 1 day
                analysis = handler.get_analysis()
                osc1_rec = (analysis.oscillators).get('RECOMMENDATION')
                sum_rec = (analysis.summary).get('RECOMMENDATION')
                ma_rec = (analysis.moving_averages).get('RECOMMENDATION')
                osc.append(osc1_rec)
                ma.append(ma_rec)
                sum1.append(sum_rec)
            x=osc[0]
    #        osc,ma,sum1 = this_job()
            label = Label(text='Hello from Kivy' + x,
                          size_hint=(.5, .5),
                          pos_hint={'center_x': .5, 'center_y': .5})
    
            
            return label
            
    
    
    if __name__ == '__main__':
        app = MainApp()
        app.run()

I also copied cacert.pem to my project folder. 

Just these lines make the screen go black. And the output with these same lines is perfect on my laptop but not just on the android.

Also, the app doesn't crash like with an error, the screen just becomes all black!!

Preeti
  • 3
  • 7
  • Have you requested for permission `INTERNET` in your buldozer spec file? – el3ien Sep 02 '20 at 09:24
  • @el3ien yes, I did. – Preeti Sep 02 '20 at 18:01
  • Maybe you are encountering https://github.com/kivy/kivy/issues/6522. Try making an asynchronous request. – Juraj Fiala Sep 03 '20 at 07:10
  • @JurajFiala you are right, now it doesn't get stuck on the black screen but it crashes. The Urlrequest line doesn't cause the crash. But the subsequent lines when I try to make it back to synchronous as I wanna process the result further and return it. request = UrlRequest(scan_url, req_body=jdata, on_success=self.on_getCloudEvents_success) works fine but the below lines throw the error. while not request.is_finished: time.sleep(1) Clock.tick() – Preeti Sep 04 '20 at 12:12

1 Answers1

0

I am answering my own question. req.wait() is synchronous. When I removed req.wait() and instead used request = UrlRequest(scan_url, req_body=jdata, on_success=self.on_get_success) . It no longer stays on the black screen.

However, I still need to find a way to return the result to the calling class.

Preeti
  • 3
  • 7
  • Tip: you can use [partial()](https://www.learnpython.org/en/Partial_functions) to pass data to `on_get_success`, in a functional-style way. – Juraj Fiala Sep 04 '20 at 13:42
  • @jurajfiala I don't want to pass data to on_success, I want the result to be used later in the code after urlrequest. Since I can't use req.wait(), I used while req.isfinished is False: sleep(1) and Clock.tick(). After this I wrote the code which needs the req.result. This works on my laptop but crashes on the android device. – Preeti Sep 04 '20 at 14:31
  • @JurajFiala https://stackoverflow.com/questions/63741136/kivy-urlrequest-how-to-return-the-result-to-the-calling-class – Preeti Sep 05 '20 at 02:35
  • Well, that makes it synchronous again, blocking the main Kivy thread, you don’t want that. If you need to return the result, you can pass the instance of the class you need to return to with partial. – Juraj Fiala Sep 05 '20 at 07:03
  • 1
    I figured the parameter passing on my own. Thanks. – Preeti Oct 10 '20 at 22:23