from kivy.app import App from kivy.uix.screenmanager import ScreenManager, Screen from kivy.uix.boxlayout import BoxLayout from kivy.properties import ObjectProperty, StringProperty from kivy.clock import Clock from time import time class ListScreen(Screen): items_box = ObjectProperty(None) def on_enter(self): start = time() for i in range(0,50): self.items_box.add_widget(ListItem('Item '+str(i))) self.items_box.bind(minimum_height=self.items_box.setter('height')) print time()-start def on_leave(self): self.items_box.clear_widgets() class ListItem(BoxLayout): title = StringProperty('') def __init__(self, title, **kwargs): super(ListItem, self).__init__(**kwargs) self.title = title class ListApp(App): sm = ScreenManager() screens = {} def build(self): self.__create_screens() ListApp.sm.add_widget(ListApp.screens['list1']) Clock.schedule_interval(self._switch, 1) return ListApp.sm def _switch(self, *args): ListApp.sm.switch_to(ListApp.screens['list1' if ListApp.sm.current != 'list1' else 'list2']) def __create_screens(self): ListApp.screens['list1'] = ListScreen(name='list1') ListApp.screens['list2'] = ListScreen(name='list2') if __name__ == '__main__': ListApp().run()
<ListScreen>: items_box: items_box BoxLayout: orientation: "vertical" AnchorLayout: size_hint_y: 0.1 padding: self.width*0.1, self.height*0.05 Label: font_size: root.height*0.05 text: "Some list" ScrollView: size_hint_y: 0.9 size: self.size BoxLayout: id: items_box orientation: "vertical" padding: self.width*0.1, 0 size_hint_y: None <ListItem>: orientation: "horizontal" size_hint_y: None height: app.sm.height*0.1 Label: font_size: app.sm.height*0.025 text: root.title size_hint_x: 0.9 text_size: self.size valign: "middle" CheckBox size_hint_x: 0.1
11-28 11:44:09.525 1848 2044 I python : 0.5793800354 11-28 11:44:10.853 1848 2044 I python : 0.453143119812 11-28 11:44:12.544 1848 2044 I python : 0.633069992065 11-28 11:44:13.697 1848 2044 I python : 0.369570970535 11-28 11:44:14.988 1848 2044 I python : 0.594089031219
from kivy.app import App from kivy.uix.screenmanager import ScreenManager, Screen from kivy.properties import ObjectProperty from kivy.clock import Clock from time import time class ListScreen(Screen): recycle_view = ObjectProperty(None) items_box = ObjectProperty(None) def on_enter(self): start = time() for i in range(0,50): self.recycle_view.data.append({'title': 'item'+str(i)}) print time()-start def on_leave(self): self.recycle_view.data = [] class ListApp(App): sm = ScreenManager() screens = {} def build(self): self.__create_screens() ListApp.sm.add_widget(ListApp.screens['list1']) Clock.schedule_interval(self._switch, 1) return ListApp.sm def _switch(self, *args): ListApp.sm.switch_to(ListApp.screens['list1' if ListApp.sm.current != 'list1' else 'list2']) def __create_screens(self): ListApp.screens['list1'] = ListScreen(name='list1') ListApp.screens['list2'] = ListScreen(name='list2') if __name__ == '__main__': ListApp().run()
<ListScreen>: recycle_view: recycle_view items_box: items_box BoxLayout: orientation: "vertical" AnchorLayout: size_hint_y: 0.1 padding: self.width*0.1, self.height*0.05 Label: font_size: root.height*0.05 text: "Some list" RecycleView: id: recycle_view size_hint: 1, 0.9 viewclass: "ListItem" RecycleBoxLayout: id: items_box orientation: "vertical" padding: self.width*0.1, 0 default_size_hint: 1, None size_hint: 1, None height: self.minimum_height <ListItem@BoxLayout>: orientation: "horizontal" size_hint: 1, None height: app.sm.height*0.1 title: '' Label: font_size: app.sm.height*0.025 text: root.title size_hint_x: 0.9 text_size: self.size valign: "middle" CheckBox size_hint_x: 0.1
11-29 13:11:58.196 13121 13203 I python : 0.00388479232788 11-29 13:11:59.192 13121 13203 I python : 0.00648307800293 11-29 13:12:00.189 13121 13203 I python : 0.00288391113281 11-29 13:12:01.189 13121 13203 I python : 0.00324606895447 11-29 13:12:03.188 13121 13203 I python : 0.00265002250671
from time import sleep if __name__ == '__main__': while True: print "myapp service" sleep(5)
from jnius import autoclass # ... # class GuessTheQuoteApp(App): # ... # def __start_service(self): service = autoclass('com.madhattersoft.guessthequote.ServiceGuessthequoteservice') mActivity = autoclass('org.kivy.android.PythonActivity').mActivity service.start(mActivity, "")
public int startType() { return START_STICKY; }
E AndroidRuntime: Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.os.Bundle android.content.Intent.getExtras()' on a null object reference
@Override public int onStartCommand(Intent intent, int flags, int startId) { if (pythonThread != null) { Log.v("python service", "service exists, do not start again"); return START_NOT_STICKY; } if (intent != null) { startIntent = intent; Bundle extras = intent.getExtras(); androidPrivate = extras.getString("androidPrivate"); androidArgument = extras.getString("androidArgument"); serviceEntrypoint = extras.getString("serviceEntrypoint"); pythonName = extras.getString("pythonName"); pythonHome = extras.getString("pythonHome"); pythonPath = extras.getString("pythonPath"); pythonServiceArgument = extras.getString("pythonServiceArgument"); pythonThread = new Thread(this); pythonThread.start(); if (canDisplayNotification()) { doStartForeground(extras); } } else { pythonThread = new Thread(this); pythonThread.start(); } return startType(); }
F DEBUG : Abort message: 'art/runtime/java_vm_ext.cc:410] JNI DETECTED ERROR IN APPLICATION: GetStringUTFChars received NULL jstring'
@Override public void run(){ String package_root = getFilesDir().getAbsolutePath(); String app_root = package_root + "/app"; File app_root_file = new File(app_root); PythonUtil.loadLibraries(app_root_file); this.mService = this; if (androidPrivate == null) { androidPrivate = package_root; } if (androidArgument == null) { androidArgument = app_root; } if (serviceEntrypoint == null) { serviceEntrypoint = "./service/main.py"; // hardcoded } if (pythonName == null) { pythonName = "guessthequoteservice"; // hardcoded } if (pythonHome == null) { pythonHome = app_root; } if (pythonPath == null) { pythonPath = package_root; } if (pythonServiceArgument == null) { pythonServiceArgument = app_root+":"+app_root+"/lib"; } nativeStart( androidPrivate, androidArgument, serviceEntrypoint, pythonName, pythonHome, pythonPath, pythonServiceArgument); stopSelf(); }
package com.madhattersoft.guessthequote; import android.content.BroadcastReceiver; import android.content.Intent; import android.content.Context; import org.kivy.android.PythonActivity; public class MyBroadcastReceiver extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { Intent ix = new Intent(context, PythonActivity.class); ix.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(ix); } }
package com.madhattersoft.guessthequote; import android.content.BroadcastReceiver; import android.content.Intent; import android.content.Context; import com.madhattersoft.guessthequote.ServiceGuessthequoteservice; public class MyBroadcastReceiver extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { Intent ix = new Intent(context, ServiceGuessthequoteservice.class); ix.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startService(ix); } }
E AndroidRuntime: java.lang.RuntimeException: Unable to start service com.madhattersoft.guessthequote.ServiceGuessthequoteservice@8c96929 with Intent { cmp=com.madhattersoft.guessthequote/.ServiceGuessthequoteservice }: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.os.Bundle.getString(java.lang.String)' on a null object reference
package import com.madhattersoft.guessthequote; import android.content.BroadcastReceiver; import android.content.Intent; import android.content.Context; import com.madhattersoft.guessthequote.ServiceGuessthequoteservice; public class MyBroadcastReceiver extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { String package_root = context.getFilesDir().getAbsolutePath(); String app_root = package_root + "/app"; Intent ix = new Intent(context, ServiceGuessthequoteservice.class); ix.putExtra("androidPrivate", package_root); ix.putExtra("androidArgument", app_root); ix.putExtra("serviceEntrypoint", "./service/main.py"); ix.putExtra("pythonName", "guessthequoteservice"); ix.putExtra("pythonHome", app_root); ix.putExtra("pythonPath", package_root); ix.putExtra("pythonServiceArgument", app_root+":"+app_root+"/lib"); ix.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startService(ix); } }
if autoclass('java.util.Locale').getDefault().getLanguage() in ('ru', 'uk', 'be'): import lang.ru as lang else: import lang.en as lang GuessTheQuote.lang = lang
app.lang.some_phrase
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">Guess The Quote</string> <string name="private_version">1517538478.81</string> <string name="presplash_color">#2EBCB2</string> <string name="urlScheme">kivy</string> </resources>
# , P4A 370 render( 'strings.tmpl.xml', 'res/values/strings.xml', args=args, url_scheme=url_scheme, ) # :) local_args = {'be': argparse.Namespace(**vars(args)), 'ru': argparse.Namespace(**vars(args)), 'uk': argparse.Namespace(**vars(args))} for key in local_args: local_args[key].name = u' !' # , , P4A buildozer, for i in os.listdir('res'): if i[:6] == 'values': render( 'strings.tmpl.xml', 'res/'+i+'/strings.xml', args=(args if i == 'values' else local_args[i[7:10]]), url_scheme=url_scheme, ) # , P4A 388 with open(join(dirname(__file__), 'res', 'values', 'strings.xml')) as fileh: lines = fileh.read() with open(join(dirname(__file__), 'res', 'values', 'strings.xml'), 'w') as fileh: fileh.write(re.sub(r'"private_version">[0-9\.]*<', '"private_version">{}<'.format( str(time.time())), lines)) # for i in os.listdir('res'): if i[:6] == 'values': with open(join(dirname(__file__), 'res', i, 'strings.xml')) as fileh: lines = fileh.read() with open(join(dirname(__file__), 'res', i, 'strings.xml'), 'w') as fileh: fileh.write(re.sub(r'"private_version">[0-9\.]*<', '"private_version">{}<'.format( str(time.time())), lines))
Source: https://habr.com/ru/post/348226/