2

C バイナリからテキストの質問を取得し、TextView に表示する必要があります。また、入力フィールドから回答を取得して C バイナリなどに渡す必要があります。このトピックを読み、Android で実行しようとしました。C バイナリはシェルで動作しますが、アプリが動作しません (空白の画面)。私はJavaが初めてで、助けが必要です。

package com.example.helloapp;

import android.app.Activity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.EditText;
import android.widget.Toast;
import android.os.Handler;
import android.os.Message;
import android.os.Bundle;
import java.io.*;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;


public class HelloApp extends Activity
{
    private Button btn;
    private EditText editText;
    private TextView textView;

    private BlockingQueue<String> m_queue;
    private BufferedReader bufIn;
    private InputStream in;
    private InputThread inputThread;
    private PrintWriter printOut;
    private Process p;

    private Handler handler;

    private String input = null;

// show nice popup on error
    private void popup(String msg)
    {
        Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
    }

    Thread.UncaughtExceptionHandler uncaughtExceptionHandler = new Thread.UncaughtExceptionHandler()
    {
        @Override
        public void uncaughtException(Thread t, Throwable e) {
            e.printStackTrace();
            HelloApp.this.finish();
        }
    };

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        textView = (TextView)findViewById(R.id.textView1);
        btn = (Button)findViewById(R.id.button1);

        Thread.setDefaultUncaughtExceptionHandler(uncaughtExceptionHandler);

// new Thread cannot change our TextView, so we use Handler
        handler = new Handler()
        {
            @Override
            public void handleMessage(Message msg)
            {
                String text = (String) msg.obj;
                textView.setText(text);
            }
        };

        File f = new File(getCacheDir()+"/hello");

        if(!f.exists())
        try {
// unpack our binary...
            InputStream is = getAssets().open("hello");
            int size = is.available();
            byte[] buffer = new byte[size];
            is.read(buffer);
            is.close();

            FileOutputStream fos = new FileOutputStream(f);
            fos.write(buffer);
            fos.close();

// ... and make it executable
            try {
                Process chmod = Runtime.getRuntime().exec("/system/bin/chmod 777 " +f.getPath());
                chmod.waitFor();
            } catch(IOException e) { popup(e.getMessage()); } catch(InterruptedException e) { popup(e.getMessage()); }

        } catch(IOException e) { popup(e.getMessage()); }

        try {
            p = Runtime.getRuntime().exec(f.getPath());

            InputStream in = p.getInputStream() ;
            OutputStream out = p.getOutputStream ();
            InputStream err = p.getErrorStream();

            printOut = new PrintWriter(out);

            m_queue = new ArrayBlockingQueue<String>(10);
            inputThread = new InputThread(in, m_queue);
            inputThread.start();

        } catch(Exception e) { popup(e.getMessage()); }


        btn.setOnClickListener(new View.OnClickListener()
        {
            public void onClick(View view)
            {
                editText = (EditText)findViewById(R.id.editText1);
                input = editText.getText().toString();
// pass something to C binary
                printOut.println(input+"\n");
                printOut.flush();
            }
        });
    }

private void setTextHandler(final String text)
{
    Message msg = new Message();
    msg.obj = text;
    handler.sendMessage(msg);
}

private void mainLoop()
{
    String line;

    while(true)
    {
            try {
            line = bufIn.readLine();

// stdin is always empty... why?

            if(line != null) { setTextHandler(line); }
        }
        catch(IOException e) { popup(e.getMessage()); return; }
    }
}

private class InputThread extends Thread
{
    InputThread(InputStream in, BlockingQueue<String> queue)
    {
        bufIn = new BufferedReader(new InputStreamReader(in));
        m_queue = queue;
    }
    public void run() {

        try { mainLoop(); }

            catch(Throwable t) { popup(t.getMessage()); }
    }
}

}

更新: 次の C コードをコンパイルすると:

#include <stdio.h>
#include <string.h>

int main(void)
{
char *s;

setvbuf(stdout, NULL, _IONBF, 0); // <<<= disable buffering globally

printf("Enter your name:\n");
fflush(stdout);
scanf("%s", &s);
printf("Hello, %s", s);
fflush(stdout);

return 0;
}

バイナリが終了した場合にのみ結果を取得します。私はAndroidアプリを実行し、空白の画面を表示し(「名前を入力してください:」を参照する必要があります)、何かを入力し、[OK]ボタンを押します-バイナリが終了し、「名前を入力してください:こんにちは、ユージーン」がすぐに表示されます。

問題が解決しました!更新された C コードを参照してください。

4

0 に答える 0