Skip to content
This repository has been archived by the owner on Jan 30, 2023. It is now read-only.

how can I call funtions from a python file? #2

Closed
hxhowl opened this issue Dec 27, 2017 · 16 comments
Closed

how can I call funtions from a python file? #2

hxhowl opened this issue Dec 27, 2017 · 16 comments

Comments

@hxhowl
Copy link

hxhowl commented Dec 27, 2017

I want to run same python files in my android project.and I config the chaquopy into my android project.Then I read the documents of API,but how can I run the python files or call python file function with those java API?

@mhsmith
Copy link
Member

mhsmith commented Dec 27, 2017

To build Python source files into your app, place them in src/main/python, as in this app. You can then call them with the Java API as in the demo app.

@hxhowl
Copy link
Author

hxhowl commented Dec 28, 2017

@mhsmith ,thank you very much,but it still not work for me.And can I run the python files in other path,like /data/data/com.example.h.demo/files?

can I connect you with other place then I can ask you this question quickly and in more detail when you are free.

@mhsmith
Copy link
Member

mhsmith commented Dec 28, 2017

To load Python files from another location, you could add that location to sys.path, or load them manually with imp.find_module.

If you're unable to load Python modules even from the standard location with Python.getModule, then you'll have to give more details of what you tried and what happened.

If you want to pay for private support, please email the contact address on our website. Otherwise, it's better to continue the discussion here so other people can benefit from it.

@hxhowl
Copy link
Author

hxhowl commented Dec 28, 2017

@mhsmith I have try like that:
MainActivity.java

public class MainActivity extends AppCompatActivity {

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

        TextView tvCaption = (TextView)findViewById(R.id.tvCaption);
        tvCaption.setText("tttttt");
        try {
            viewSource(this, "hello.py");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private static final String ASSET_SOURCE_DIR = "source";
    private static final String EXTRA_CSS =
            "body { background-color: #eeeeee; font-size: 85%; }";

    // Compare with the equivalent Python code in chaquopy/demo/utils.py
    private static void viewSource(Context context,
                                   String filename) throws IOException {
        if (! Python.isStarted()) {
            Python.start(new AndroidPlatform(context));
        }
        InputStream stream = context.getAssets().open
                (ASSET_SOURCE_DIR + "/" + filename);
        BufferedReader reader =
                new BufferedReader(new InputStreamReader(stream));
        String text = "";
        String line;
        while ((line = reader.readLine()) != null) {
            text += line + "\n";
        }
        Python py = Python.getInstance();
        PyObject pym =py.getModule("hello");
        PyObject pyf = pym.callAttr("test");
    }
}

hello.py

def test():
    print('hello chaquopy with python3.6.3')

if '__name__' == '__main__':
    test()

But it not work.

@mhsmith
Copy link
Member

mhsmith commented Dec 28, 2017

I assume you didn't receive any error: if you did receive one, then please say what it was.

Standard output is ignored by default in Android apps (this applies to Java just as much as Python), so I wouldn't expect your script output to be visible anywhere. The easiest starting point to make it visible would be to use the UnitTestActivity from the demo app, i.e. something like this (untested but should be pretty close):

public class MainActivity extends UnitTestActivity {
    @Override
    protected void runTests() {
        Python py = Python.getInstance();
        PyObject pym = py.getModule("hello");
        PyObject pyf = pym.callAttr("test");
    }
}

You'll also need to include a few resource files used by the base activity: build errors should indicate which ones.

@hxhowl
Copy link
Author

hxhowl commented Dec 29, 2017

@mhsmith ,I try add UnitTestActivity and ConsoleActivity and other resouce into the project,and change the MainActivity like your answer.
MainActivity.java

import com.chaquo.python.*;
import com.chaquo.python.android.AndroidPlatform;

public class MainActivity extends UnitTestActivity {
    @Override
    protected void runTests() {
        if (! Python.isStarted()) {
            Python.start(new AndroidPlatform(this));

        }
        Python py = Python.getInstance();
        PyObject pym = py.getModule("hello");
        PyObject pyf = pym.callAttr("test");
    }
}

Then get the error:

12-29 10:36:37.778 6839-6839/com.example.huangchp.mychaquopyapplication E/AndroidRuntime: FATAL EXCEPTION: main
                                                                                          Process: com.example.huangchp.mychaquopyapplication, PID: 6839
                                                                                          java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.huangchp.mychaquopyapplication/com.example.huangchp.mychaquopyapplication.MainActivity}: java.lang.RuntimeException: Cannot use GenericPlatform on Android. Call Python.start(new AndroidPlatform(context)) before using Python, or use PyApplication to do this automatically.
                                                                                              at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2334)
                                                                                              at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2483)
                                                                                              at android.app.ActivityThread.access$900(ActivityThread.java:153)
                                                                                              at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1349)
                                                                                              at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                                              at android.os.Looper.loop(Looper.java:148)
                                                                                              at android.app.ActivityThread.main(ActivityThread.java:5441)
                                                                                              at java.lang.reflect.Method.invoke(Native Method)
                                                                                              at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:738)
                                                                                              at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:628)
                                                                                           Caused by: java.lang.RuntimeException: Cannot use GenericPlatform on Android. Call Python.start(new AndroidPlatform(context)) before using Python, or use PyApplication to do this automatically.
                                                                                              at com.chaquo.python.GenericPlatform.<init>(GenericPlatform.java:9)
                                                                                              at com.chaquo.python.Python.getInstance(Python.java:28)
                                                                                              at com.example.huangchp.mychaquopyapplication.ConsoleActivity.<init>(ConsoleActivity.java:14)
                                                                                              at com.example.huangchp.mychaquopyapplication.UnitTestActivity.<init>(UnitTestActivity.java:0)
                                                                                              at com.example.huangchp.mychaquopyapplication.MainActivity.<init>(MainActivity.java:0)
                                                                                              at java.lang.Class.newInstance(Native Method)
                                                                                              at android.app.Instrumentation.newActivity(Instrumentation.java:1068)
                                                                                              at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2324)
                                                                                              at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2483) 
                                                                                              at android.app.ActivityThread.access$900(ActivityThread.java:153) 
                                                                                              at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1349) 
                                                                                              at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                                                              at android.os.Looper.loop(Looper.java:148) 
                                                                                              at android.app.ActivityThread.main(ActivityThread.java:5441) 
                                                                                              at java.lang.reflect.Method.invoke(Native Method) 
                                                                                              at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:738) 
                                                                                              at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:628) 

@mhsmith
Copy link
Member

mhsmith commented Dec 29, 2017

Starting Python in that method is too late because Python is also used by the ConsoleActivity base class. The easiest fix would be to use PyApplication.

Alternatively, change ConsoleActivity to call Python.getInstance in onCreate rather than in a field initializer, and then start Python in your own onCreate before calling super.onCreate.

@mhsmith
Copy link
Member

mhsmith commented Jan 4, 2018

Have you been able to make it work?

@hushanhsiang
Copy link

hushanhsiang commented Jan 9, 2018

I suggest to put "Quick Start" an example .py as "Hello Chaquopy" in Chaquopy web site.

And more simple examples which like how to use Android Component to indicate pictures, take picture, to use compass, GPS with Google API.....

@hxhowl
Copy link
Author

hxhowl commented Jan 9, 2018

@mhsmith thank you for help,I not make it work. I think this solution maybe more difficult for me.When I try an another solution starcore_for_android ,I think is more suitable for me.
I agree with @hushanhsiang ,Maybe more detail example can more friendly to "Quick Start".

@mhsmith
Copy link
Member

mhsmith commented Jan 9, 2018

@zcanfly Please try using PyApplication as shown here:

<application
android:name="com.chaquo.python.android.PyApplication"

If that still doesn't work, please let me know what happens.

I agree it's not easy enough to run a simple Python console script. We'll release another example app soon for that use case. Also, the next Chaquopy version will send stdout and stderr to the Android logcat, just like in Java.

@mhsmith
Copy link
Member

mhsmith commented Jan 9, 2018

@hushanhsiang The principles of how to use Android APIs in Chaquopy should be clear from the UI demo here:

https://github.com/chaquo/chaquopy/blob/master/app/src/main/python/chaquopy/demo/ui_demo.py

You should be able to translate examples of any other APIs from Java to Python in the same way, including the things you mention.

@hushanhsiang
Copy link

hushanhsiang commented Jan 10, 2018

(Moved unrelated question to chaquo/chaquopy#22 -- mhsmith)

@mhsmith
Copy link
Member

mhsmith commented Mar 6, 2018

@zcanfly: please have a look at the chaquopy-console project: it provides an easy way to run text-based Python programs on Android.

@mhsmith mhsmith closed this as completed Mar 6, 2018
@wyh5625
Copy link

wyh5625 commented Jan 30, 2019

It's required to pass a java class as a base class in StaticProxy. How to set StaticProxy of a python class which inheritate another python class? And if the python class contains dependencies(e.g. import six), just need to include the dependency in gradle?

@mhsmith
Copy link
Member

mhsmith commented Jan 30, 2019

You can inherit from Python classes, as long as the static_proxy expression comes first. For example:

class Example(static_proxy(), PythonClass):

Since no Java base classes are specified here, Java will see this class as inheriting only from java.lang.Object.

Dependencies are installed through build.gradle as described in the documentation. If you have a specific question about that, please create an issue in the main Chaquopy project.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants