Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/203.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 使用messenger下载图像的绑定服务_Android - Fatal编程技术网

Android 使用messenger下载图像的绑定服务

Android 使用messenger下载图像的绑定服务,android,Android,我无法在boundservice中使用messenger下载图像,即使在android清单中显示单独进程中的服务 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="edu.vuum.mocca" android:versionCode="1" android:version

我无法在boundservice中使用messenger下载图像,即使在android清单中显示单独进程中的服务

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="edu.vuum.mocca"
    android:versionCode="1"
    android:versionName="1.0" >
<uses-permission android:name="android.permission.INTERNET"></uses-permission> 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="19" />
<supports-screens android:smallScreens="false" android:xlargeScreens="true" android:normalScreens="true" android:largeScreens="true"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" 
        android:uiOptions="splitActionBarWhenNarrow">
        <activity
            android:name="edu.vuum.mocca.DownloadActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
       <service android:name="edu.vuum.mocca.DownloadService" android:process=":my_process"/>

    </application>

</manifest>
downloadactivity downloadimage方法,当用户单击downloadimage按钮以使用DownloadService下载图像时调用

package edu.vuum.mocca;

import java.lang.ref.WeakReference;



import android.app.Activity;
import android.app.ProgressDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;

/**
 * @class DownloadActivity
 * 
 * @brief A class that allows a user to download a bitmap image using
 *        a DownloadService.
 */
public class DownloadActivity extends Activity {
    /**
     * Used for debugging.
     */
    private final String TAG = getClass().getName();
    private final static int LOG_OP = 1;
    private final static String MESSAGE_URL = "course.examples.Services.Logging.MESSAGE";
    private boolean mIsBound;
    /**
     * User's selection of URL to download
     */
    private EditText mUrlEditText;

    /**
     * Image that's been downloaded
     */
    private ImageView mImageView;

    /**
     * Default URL.
     */
    private String mDefaultUrl = 
        "http://www.dre.vanderbilt.edu/~schmidt/ka.png";

    /**
     * Display progress of download
     */
    private ProgressDialog mProgressDialog;


    /**
     * Reference to the Messenger that's implemented in the
     * UniqueIDGeneratorService.
     */
    private Messenger mMessengerRef = null;

    /** 
     * This ServiceConnection is used to receive a Messenger proxy
     * after binding to the UniqueIDGeneratorService using bindService().
     */
    private ServiceConnection mConnection = new ServiceConnection() {
            /**
             * Called after the UniqueIDGeneratorService is connected to
             * convey the result returned from onBind().
             */
            public void onServiceConnected(ComponentName className,
                                           IBinder messenger) {
                //Log.d(TAG, "ComponentName:" + className);

                // Create a newq Messenger that encapsulates the
                // returned IBinder object and store it for later use
                // in mMessengerRef.
                mMessengerRef = new Messenger(messenger);
                mIsBound = true;
            }

            /**
             * Called if the Service crashes and is no longer
             * available.  The ServiceConnection will remain bound,
             * but the service will not respond to any requests.
             */
            public void onServiceDisconnected(ComponentName className) {
                mMessengerRef = null;


                mIsBound = false;
            }
    };


    /**
     * Method that initializes the Activity when it is first created.
     * 
     * @param savedInstanceState
     *            Activity's previously frozen state, if there was one.
     */
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        /**
         * Sets the content view specified in the main.xml file.
         */
        setContentView(R.layout.main);

        /**
         * Caches references to the EditText and ImageView objects in
         * data members to optimize subsequent access.
         */
        mUrlEditText = (EditText) findViewById(R.id.mUrlEditText);
        mImageView = (ImageView) findViewById(R.id.mImageView);
    }

    /**
     * Show a toast, notifying a user of an error when retrieving a
     * bitmap.
     */
    void showErrorToast(String errorString) {
        Toast.makeText(this,
                       errorString,
                       Toast.LENGTH_LONG).show();
    }

    /**
     * Display a downloaded bitmap image if it's non-null; otherwise,
     * it reports an error via a Toast.
     * 
     * @param image
     *            The bitmap image
     */
    void displayImage(Bitmap image)
    {   
        if (mImageView == null)
            showErrorToast("Problem with Application,"
                           + " please contact the Developer.");
        else if (image != null)
            mImageView.setImageBitmap(image);
        else
            showErrorToast("image is corrupted,"
                           + " please check the requested URL.");
    }

    /**
     * Called when a user clicks a button to reset an image to
     * default.
     * 
     * @param view
     *            The "Reset Image" button
     */
    public void resetImage(View view) {
        mImageView.setImageResource(R.drawable.default_image);
    }

    /**
     * Called when a user clicks the Download Image button to download
     * an image using the DownloadService
     * 
     * @param view
     *            The "Download Image" button
     */
    public void downloadImage(View view) {
        // Obtain the requested URL from the user input.
        if (mIsBound) {
        String url = getUrlString();

        Log.e(DownloadActivity.class.getSimpleName(),
              "Downloading " + url);

        hideKeyboard();

        // Inform the user that the download is starting.
        showDialog("downloading via startService()");
     // Create a request Message that indicates the Service should
        // send the reply back to ReplyHandler encapsulated by the
        // Messenger.
        Message msg = Message.obtain(null, LOG_OP);
        Bundle bundle = new Bundle();
        bundle.putString(MESSAGE_URL, url);
        msg.setData(bundle);

       // Message request = Message.obtain();
        msg.replyTo = new Messenger(new DownloadHandler(this));

        try {
            if (mMessengerRef != null) {
                Log.d(TAG, "sending message to service with url");
                // Send the request Message to the
                // UniqueIDGeneratorService.
                mMessengerRef.send(msg);
            }
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        // Create an Intent to download an image in the background via
        // a Service.  The downloaded image is later diplayed in the
        // UI Thread via the downloadHandler() method defined below.
     //  DownloadService.makeIntent(this, Uri.parse( getUrlString()));

        }else{
            Log.d(TAG, "service is not bounded restat again");
        }
    }
    /**
     * Hook method called by Android when this Activity becomes
     * visible.
     */
    @Override
    protected void onStart() {
        super.onStart();
        Log.d(TAG, "onStart()");

        Log.d(TAG, "calling bindService()");
        if (mMessengerRef == null)
            // Bind to the UniqueIDGeneratorService associated with this
            // Intent.
            bindService(DownloadService.makeIntent(this),
                        this.mConnection,
                        Context.BIND_AUTO_CREATE);
    }
    @Override
    protected void onStop() {
         super.onStop();
         if (mIsBound)
            unbindService(mConnection);
    }

    /**
     * @class DownloadHandler
     *
     * @brief An inner class that inherits from Handler and uses its
     *        handleMessage() hook method to process Messages sent to
     *        it from the DownloadService.
     */
    private static class DownloadHandler extends Handler {
        /**
         * Allows Activity to be garbage collected properly.
         */
        private WeakReference<DownloadActivity> mActivity;

        /**
         * Class constructor constructs mActivity as weak reference
         * to the activity
         * 
         * @param activity
         *            The corresponding activity
         */
        public DownloadHandler(DownloadActivity activity) {
            mActivity = new WeakReference<DownloadActivity>(activity);
        }

        /**
        /**
         * This hook method is dispatched in response to receiving
         * the pathname back from the DownloadService.
         */
        public void handleMessage(Message msg) {
            DownloadActivity activity = mActivity.get();
            // Bail out of the DownloadActivity is gone.
            if (activity == null)
                return;

            // Extract the data from Message, which is in the form
            // of a Bundle that can be passed across processes.
            Bundle data = msg.getData();

            // Extract the pathname from the Bundle.
            String pathname = data.getString("PATHNAME");

            // See if things worked or not.
            if (msg.arg1 != RESULT_OK || pathname == null)
                activity.showDialog("failed download");

            // Stop displaying the progress dialog.
            activity.dismissDialog();

            // Display the image in the UI Thread.
            activity.displayImage(BitmapFactory.decodeFile(pathname));
        }
    };



    /**
     * Display the Dialog to the User.
     * 
     * @param message 
     *          The String to display what download method was used.
     */
    public void showDialog(String message) {
        mProgressDialog =
            ProgressDialog.show(this,
                                "Download",
                                message,
                                true);
    }

    /**
     * Dismiss the Dialog
     */
    public void dismissDialog() {
        if (mProgressDialog != null)
            mProgressDialog.dismiss();
    }

    /**
     * Hide the keyboard after a user has finished typing the url.
     */
    private void hideKeyboard() {
        InputMethodManager mgr =
            (InputMethodManager) getSystemService
            (Context.INPUT_METHOD_SERVICE);
        mgr.hideSoftInputFromWindow(mUrlEditText.getWindowToken(),
                                    0);
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.download, menu);
        return true;
    }




    /**
     * Read the URL EditText and return the String it contains.
     * 
     * @return String value in mUrlEditText
     */
    String getUrlString() {
        String s = mUrlEditText.getText().toString();
        if (s.equals(""))
            s = mDefaultUrl;
        return s;
    }

}
使用messenger绑定服务,如果它在单独的进程中运行,则不需要单独的线程来执行长时间运行的任务

我需要知道为什么这个下载图像的服务不工作,即使它在单独的进程中运行


感谢您的帮助。

由于存在NetworkMainThreadException,解决方案是将网络代码放入异步任务或线程中。

如果可能,请将问题缩小到您的问题,它似乎太长了。我想使用boundservice meseenger进行长时间运行的过程下载图像。我的问题是,为什么我的HandleMessage服务在单独的过程中运行时没有加载图像,尽管服务给出了错误android.os.NetworkOnMainThreadException作为网络代码,请解释一下。或者,只有一个选项可以执行长时间运行的任务,因为backgroundthreadNetwork代码是当您的应用程序连接到internet或LAN上的服务器并使用流发送或接收数据时执行的所有代码。
package edu.vuum.mocca;

import java.lang.ref.WeakReference;



import android.app.Activity;
import android.app.ProgressDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;

/**
 * @class DownloadActivity
 * 
 * @brief A class that allows a user to download a bitmap image using
 *        a DownloadService.
 */
public class DownloadActivity extends Activity {
    /**
     * Used for debugging.
     */
    private final String TAG = getClass().getName();
    private final static int LOG_OP = 1;
    private final static String MESSAGE_URL = "course.examples.Services.Logging.MESSAGE";
    private boolean mIsBound;
    /**
     * User's selection of URL to download
     */
    private EditText mUrlEditText;

    /**
     * Image that's been downloaded
     */
    private ImageView mImageView;

    /**
     * Default URL.
     */
    private String mDefaultUrl = 
        "http://www.dre.vanderbilt.edu/~schmidt/ka.png";

    /**
     * Display progress of download
     */
    private ProgressDialog mProgressDialog;


    /**
     * Reference to the Messenger that's implemented in the
     * UniqueIDGeneratorService.
     */
    private Messenger mMessengerRef = null;

    /** 
     * This ServiceConnection is used to receive a Messenger proxy
     * after binding to the UniqueIDGeneratorService using bindService().
     */
    private ServiceConnection mConnection = new ServiceConnection() {
            /**
             * Called after the UniqueIDGeneratorService is connected to
             * convey the result returned from onBind().
             */
            public void onServiceConnected(ComponentName className,
                                           IBinder messenger) {
                //Log.d(TAG, "ComponentName:" + className);

                // Create a newq Messenger that encapsulates the
                // returned IBinder object and store it for later use
                // in mMessengerRef.
                mMessengerRef = new Messenger(messenger);
                mIsBound = true;
            }

            /**
             * Called if the Service crashes and is no longer
             * available.  The ServiceConnection will remain bound,
             * but the service will not respond to any requests.
             */
            public void onServiceDisconnected(ComponentName className) {
                mMessengerRef = null;


                mIsBound = false;
            }
    };


    /**
     * Method that initializes the Activity when it is first created.
     * 
     * @param savedInstanceState
     *            Activity's previously frozen state, if there was one.
     */
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        /**
         * Sets the content view specified in the main.xml file.
         */
        setContentView(R.layout.main);

        /**
         * Caches references to the EditText and ImageView objects in
         * data members to optimize subsequent access.
         */
        mUrlEditText = (EditText) findViewById(R.id.mUrlEditText);
        mImageView = (ImageView) findViewById(R.id.mImageView);
    }

    /**
     * Show a toast, notifying a user of an error when retrieving a
     * bitmap.
     */
    void showErrorToast(String errorString) {
        Toast.makeText(this,
                       errorString,
                       Toast.LENGTH_LONG).show();
    }

    /**
     * Display a downloaded bitmap image if it's non-null; otherwise,
     * it reports an error via a Toast.
     * 
     * @param image
     *            The bitmap image
     */
    void displayImage(Bitmap image)
    {   
        if (mImageView == null)
            showErrorToast("Problem with Application,"
                           + " please contact the Developer.");
        else if (image != null)
            mImageView.setImageBitmap(image);
        else
            showErrorToast("image is corrupted,"
                           + " please check the requested URL.");
    }

    /**
     * Called when a user clicks a button to reset an image to
     * default.
     * 
     * @param view
     *            The "Reset Image" button
     */
    public void resetImage(View view) {
        mImageView.setImageResource(R.drawable.default_image);
    }

    /**
     * Called when a user clicks the Download Image button to download
     * an image using the DownloadService
     * 
     * @param view
     *            The "Download Image" button
     */
    public void downloadImage(View view) {
        // Obtain the requested URL from the user input.
        if (mIsBound) {
        String url = getUrlString();

        Log.e(DownloadActivity.class.getSimpleName(),
              "Downloading " + url);

        hideKeyboard();

        // Inform the user that the download is starting.
        showDialog("downloading via startService()");
     // Create a request Message that indicates the Service should
        // send the reply back to ReplyHandler encapsulated by the
        // Messenger.
        Message msg = Message.obtain(null, LOG_OP);
        Bundle bundle = new Bundle();
        bundle.putString(MESSAGE_URL, url);
        msg.setData(bundle);

       // Message request = Message.obtain();
        msg.replyTo = new Messenger(new DownloadHandler(this));

        try {
            if (mMessengerRef != null) {
                Log.d(TAG, "sending message to service with url");
                // Send the request Message to the
                // UniqueIDGeneratorService.
                mMessengerRef.send(msg);
            }
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        // Create an Intent to download an image in the background via
        // a Service.  The downloaded image is later diplayed in the
        // UI Thread via the downloadHandler() method defined below.
     //  DownloadService.makeIntent(this, Uri.parse( getUrlString()));

        }else{
            Log.d(TAG, "service is not bounded restat again");
        }
    }
    /**
     * Hook method called by Android when this Activity becomes
     * visible.
     */
    @Override
    protected void onStart() {
        super.onStart();
        Log.d(TAG, "onStart()");

        Log.d(TAG, "calling bindService()");
        if (mMessengerRef == null)
            // Bind to the UniqueIDGeneratorService associated with this
            // Intent.
            bindService(DownloadService.makeIntent(this),
                        this.mConnection,
                        Context.BIND_AUTO_CREATE);
    }
    @Override
    protected void onStop() {
         super.onStop();
         if (mIsBound)
            unbindService(mConnection);
    }

    /**
     * @class DownloadHandler
     *
     * @brief An inner class that inherits from Handler and uses its
     *        handleMessage() hook method to process Messages sent to
     *        it from the DownloadService.
     */
    private static class DownloadHandler extends Handler {
        /**
         * Allows Activity to be garbage collected properly.
         */
        private WeakReference<DownloadActivity> mActivity;

        /**
         * Class constructor constructs mActivity as weak reference
         * to the activity
         * 
         * @param activity
         *            The corresponding activity
         */
        public DownloadHandler(DownloadActivity activity) {
            mActivity = new WeakReference<DownloadActivity>(activity);
        }

        /**
        /**
         * This hook method is dispatched in response to receiving
         * the pathname back from the DownloadService.
         */
        public void handleMessage(Message msg) {
            DownloadActivity activity = mActivity.get();
            // Bail out of the DownloadActivity is gone.
            if (activity == null)
                return;

            // Extract the data from Message, which is in the form
            // of a Bundle that can be passed across processes.
            Bundle data = msg.getData();

            // Extract the pathname from the Bundle.
            String pathname = data.getString("PATHNAME");

            // See if things worked or not.
            if (msg.arg1 != RESULT_OK || pathname == null)
                activity.showDialog("failed download");

            // Stop displaying the progress dialog.
            activity.dismissDialog();

            // Display the image in the UI Thread.
            activity.displayImage(BitmapFactory.decodeFile(pathname));
        }
    };



    /**
     * Display the Dialog to the User.
     * 
     * @param message 
     *          The String to display what download method was used.
     */
    public void showDialog(String message) {
        mProgressDialog =
            ProgressDialog.show(this,
                                "Download",
                                message,
                                true);
    }

    /**
     * Dismiss the Dialog
     */
    public void dismissDialog() {
        if (mProgressDialog != null)
            mProgressDialog.dismiss();
    }

    /**
     * Hide the keyboard after a user has finished typing the url.
     */
    private void hideKeyboard() {
        InputMethodManager mgr =
            (InputMethodManager) getSystemService
            (Context.INPUT_METHOD_SERVICE);
        mgr.hideSoftInputFromWindow(mUrlEditText.getWindowToken(),
                                    0);
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.download, menu);
        return true;
    }




    /**
     * Read the URL EditText and return the String it contains.
     * 
     * @return String value in mUrlEditText
     */
    String getUrlString() {
        String s = mUrlEditText.getText().toString();
        if (s.equals(""))
            s = mDefaultUrl;
        return s;
    }

}