0

基本上我可以成功添加照片,但它只是显示强制关闭对话框而不是成功消息。或者如果图像太大,它会显示“虚拟内存过载......”我需要知道导致它强制关闭的问题是什么。漏窗?

public class Admin_EditRestaurantImage extends Activity{

// declare TAG and URL for interaction with PHP JSON purpose
private static final String TAG_RID = "rid"; 
private static final String TAG_SUCCESS = "success";
private static final String TAG_MESSAGE = "message";
private static final String uploadImageURL = "http://192.168.224.1/FYP/admin_updateRestaurantImage.php";
private ProgressDialog pDialog;

//constructor
ListValuePairs lvp = new ListValuePairs();
JSONParser jsonParser = new JSONParser();

//variables
EditText name;
String rid, uripath, image, imgname;
Uri currImageURI;
Intent getI;
int success;
Vibrator vibrator;

//declare main
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.restaurant_updateimage);

    vibrator = (Vibrator) getSystemService(getApplicationContext().VIBRATOR_SERVICE);

    //get intent and the value from previous layout
    getI = getIntent();
    rid = getI.getStringExtra(TAG_RID);


    //initialized gallerybtn
    Button gallerybtn = (Button)findViewById(R.id.gallerybtn_updateimage);
    gallerybtn.setOnClickListener(new OnClickListener(){
        public void onClick(View view){

            //set vibrate for 0.5 seconds whenever the button is clicked
            vibrator.vibrate(50);

            //to open up a gallery browser
            Intent imageI = new Intent();
            imageI.setType("image/*");
            imageI.setAction(Intent.ACTION_GET_CONTENT);
            startActivityForResult(Intent.createChooser(imageI,"Select Picture.."),1);          

        }

    });

    //initialized uploadbtn
    Button uploadbtn = (Button)findViewById(R.id.uploadbtn_updateimage);
    uploadbtn.setOnClickListener(new OnClickListener(){
        public void onClick(View view){

            //set vibrate for 0.5 seconds whenever the button is clicked
            vibrator.vibrate(50);

            // assign to XML layout and retrieve value into variables
            name = (EditText)findViewById(R.id.name_updateimage);
            imgname = name.getText().toString();

            //check if the fields is empty or not
            if (imgname.trim().length() <1){

                //if yes, toast error message to user
                Toast.makeText(getBaseContext(), "Please name your picture..", Toast.LENGTH_LONG).show();
            }else{

                image = imgname + ".jpg";

                //execute httpuploader class
                new HttpUploader().execute(getRealPathFromURI(currImageURI));       
            }
        }

    });

} // end of main

// To handle when an image is selected from the browser
public void onActivityResult(int requestCode, int resultCode, Intent data){
    if (resultCode == RESULT_OK) {
        if (requestCode == 1) {

            // currImageURI is the global variable to hold the content
            currImageURI = data.getData();
            uripath = getRealPathFromURI(currImageURI);

            // check log cat from response
            Log.e("upload image path contains = " , uripath);

            // assign to XML layout and set value into the view
            TextView path = (TextView) findViewById(R.id.path_updateimage);
            path.setText(getRealPathFromURI(currImageURI));
            ImageView image_view = (ImageView) findViewById(R.id.image_updateimage);
            image_view.setImageURI(currImageURI);

        }

    }
}

//Convert the image URI to the direct file system path of the image file
public String getRealPathFromURI( Uri contentUri) {
    String [] proj={MediaStore.Images.Media.DATA};
    Cursor cursor = managedQuery(contentUri,
            proj,     // columns to return
            null,     // WHERE clause; which rows to return (all rows)
            null,     // WHERE clause selection arguments (none)
            null);     // Order-by clause (ascending by name)
    int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
    cursor.moveToFirst();
    String c = cursor.getString(column_index); 
    return c;
}

//======================================================================
//create async class for HttpUploader 
public class HttpUploader extends AsyncTask<String,Void,String> {

    //show dialog to user what is going on
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pDialog = new ProgressDialog(Admin_EditRestaurantImage.this);
        pDialog.setMessage("Uploading Image... Please wait..");
        pDialog.setIndeterminate(false);
        pDialog.setCancelable(true);
        pDialog.show();
    }

    //create background thread
    protected String doInBackground(String... path) {

        try{
            for (String sdPath : path) {
                Log.e("path got what",sdPath);
                Bitmap bitmapOrg = BitmapFactory.decodeFile(sdPath);
                ByteArrayOutputStream bao = new ByteArrayOutputStream();

                //Resize the image
                double width = bitmapOrg.getWidth();
                double height = bitmapOrg.getHeight();
                double ratio = 400/width;
                int newheight = (int)(ratio*height);

                bitmapOrg = Bitmap.createScaledBitmap(bitmapOrg, 400, newheight, true);

                //Here you can define .PNG as well
                bitmapOrg.compress(Bitmap.CompressFormat.JPEG, 75, bao);
                byte[] ba = bao.toByteArray();
                String ba1=Base64.encodeBytes(ba);

                //call editRestaurantImage function from ListValuePair to converted them into value pairs data then pass value through json
                List<NameValuePair> params_uploadImg = lvp.editRestaurantImage(rid, ba1, image);
                JSONObject json = jsonParser.makeHttpRequest(uploadImageURL, "POST", params_uploadImg);

                //track the values in the json by using Log
                Log.e("image json contains = ", json.toString());

                //clear the memory of image allocation previously
                //bitmapOrg.recycle();

                // check for success tag
                success = json.getInt(TAG_SUCCESS);

                //if the success is equals to 1
                if(success == 1){

                    //toast successful message to user
                    Toast.makeText(getApplicationContext(), json.getString(TAG_MESSAGE) , Toast.LENGTH_SHORT).show();
                }else{
                    //toast error message to user
                    Toast.makeText(getApplicationContext(), json.getString(TAG_MESSAGE) , Toast.LENGTH_SHORT).show();
                }




            } // end of for loop
        }catch(JSONException e){
            e.printStackTrace();
        }
        return null;

    }

    //create ending process 
    protected void onPostExecute(String string) {

        // dismiss the dialog once got all details  
        pDialog.dismiss();
    }
} // end of HttpUploader class

} // end of class

logcat 显示我找不到的东西。我检查了显示第 208、1、165、108 行的行,它们根本没有问题。漏窗是什么意思?

05-17 18:43:46.319: E/upload image path contains =(4980): /mnt/sdcard/DCIM/100MEDIA/IMAG0133.jpg
05-17 18:43:46.369: D/dalvikvm(4980): GC_EXTERNAL_ALLOC freed 666K, 47% free 3525K/6535K, external 1178K/1690K, paused 29ms
05-17 18:43:47.681: D/View(4980): onTouchEvent: viewFlags: 0x18004001
05-17 18:43:47.681: D/View(4980): onTouchEvent: isFocusable: true, isFocusableInTouchMode: false, isFocused: false; focusTaken: false
05-17 18:43:47.701: D/WindowManagerImpl(4980): addView, new view, mViews[2]: com.android.internal.policy.impl.PhoneWindow$DecorView@40518d30
05-17 18:43:47.721: E/path got what(4980): /mnt/sdcard/DCIM/100MEDIA/IMAG0133.jpg
05-17 18:43:47.781: D/dalvikvm(4980): GC_EXTERNAL_ALLOC freed 88K, 47% free 3486K/6535K, external 16892K/18940K, paused 40ms
05-17 18:43:48.572: I/dalvikvm-heap(4980): Clamp target GC heap from 32.611MB to 32.000MB
05-17 18:43:48.572: D/dalvikvm(4980): GC_FOR_MALLOC freed 221K, 44% free 3779K/6663K, external 25271K/26797K, paused 27ms
05-17 18:43:48.832: E/image json contains =(4980): {"message":"Image Successfully Updated!","success":1}
05-17 18:43:48.832: W/dalvikvm(4980): threadid=17: thread exiting with uncaught exception (group=0x4001d5a0)
05-17 18:43:48.842: E/AndroidRuntime(4980): FATAL EXCEPTION: AsyncTask #3
05-17 18:43:48.842: E/AndroidRuntime(4980): java.lang.RuntimeException: An error occured while executing doInBackground()
05-17 18:43:48.842: E/AndroidRuntime(4980):     at android.os.AsyncTask$3.done(AsyncTask.java:200)
05-17 18:43:48.842: E/AndroidRuntime(4980):     at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274)
05-17 18:43:48.842: E/AndroidRuntime(4980):     at java.util.concurrent.FutureTask.setException(FutureTask.java:125)
05-17 18:43:48.842: E/AndroidRuntime(4980):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308)
05-17 18:43:48.842: E/AndroidRuntime(4980):     at java.util.concurrent.FutureTask.run(FutureTask.java:138)
05-17 18:43:48.842: E/AndroidRuntime(4980):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
05-17 18:43:48.842: E/AndroidRuntime(4980):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
05-17 18:43:48.842: E/AndroidRuntime(4980):     at java.lang.Thread.run(Thread.java:1027)
05-17 18:43:48.842: E/AndroidRuntime(4980): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
05-17 18:43:48.842: E/AndroidRuntime(4980):     at android.os.Handler.<init>(Handler.java:121)
05-17 18:43:48.842: E/AndroidRuntime(4980):     at android.widget.Toast.<init>(Toast.java:68)
05-17 18:43:48.842: E/AndroidRuntime(4980):     at android.widget.Toast.makeText(Toast.java:231)
05-17 18:43:48.842: E/AndroidRuntime(4980):     at com.example.pras.Admin_EditRestaurantImage$HttpUploader.doInBackground(Admin_EditRestaurantImage.java:208)
05-17 18:43:48.842: E/AndroidRuntime(4980):     at com.example.pras.Admin_EditRestaurantImage$HttpUploader.doInBackground(Admin_EditRestaurantImage.java:1)
05-17 18:43:48.842: E/AndroidRuntime(4980):     at android.os.AsyncTask$2.call(AsyncTask.java:185)
05-17 18:43:48.842: E/AndroidRuntime(4980):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
05-17 18:43:48.842: E/AndroidRuntime(4980):     ... 4 more
05-17 18:43:49.192: D/WindowManagerImpl(4980): finishRemoveViewLocked, mViews[1]: com.android.internal.policy.impl.PhoneWindow$DecorView@405aa558
05-17 18:43:49.202: E/WindowManager(4980): Activity com.example.pras.Admin_EditRestaurantImage has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@40518d30 that was originally added here
05-17 18:43:49.202: E/WindowManager(4980): android.view.WindowLeaked: Activity com.example.pras.Admin_EditRestaurantImage has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@40518d30 that was originally added here
05-17 18:43:49.202: E/WindowManager(4980):  at android.view.ViewRoot.<init>(ViewRoot.java:278)
05-17 18:43:49.202: E/WindowManager(4980):  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:149)
05-17 18:43:49.202: E/WindowManager(4980):  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
05-17 18:43:49.202: E/WindowManager(4980):  at android.view.Window$LocalWindowManager.addView(Window.java:433)
05-17 18:43:49.202: E/WindowManager(4980):  at android.app.Dialog.show(Dialog.java:265)
05-17 18:43:49.202: E/WindowManager(4980):  at com.example.pras.Admin_EditRestaurantImage$HttpUploader.onPreExecute(Admin_EditRestaurantImage.java:165)
05-17 18:43:49.202: E/WindowManager(4980):  at android.os.AsyncTask.execute(AsyncTask.java:391)
05-17 18:43:49.202: E/WindowManager(4980):  at com.example.pras.Admin_EditRestaurantImage$2.onClick(Admin_EditRestaurantImage.java:108)
05-17 18:43:49.202: E/WindowManager(4980):  at android.view.View.performClick(View.java:2533)
05-17 18:43:49.202: E/WindowManager(4980):  at android.view.View$PerformClick.run(View.java:9320)
05-17 18:43:49.202: E/WindowManager(4980):  at android.os.Handler.handleCallback(Handler.java:587)
05-17 18:43:49.202: E/WindowManager(4980):  at android.os.Handler.dispatchMessage(Handler.java:92)
05-17 18:43:49.202: E/WindowManager(4980):  at android.os.Looper.loop(Looper.java:150)
05-17 18:43:49.202: E/WindowManager(4980):  at android.app.ActivityThread.main(ActivityThread.java:4385)
05-17 18:43:49.202: E/WindowManager(4980):  at java.lang.reflect.Method.invokeNative(Native Method)
05-17 18:43:49.202: E/WindowManager(4980):  at java.lang.reflect.Method.invoke(Method.java:507)
05-17 18:43:49.202: E/WindowManager(4980):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:849)
05-17 18:43:49.202: E/WindowManager(4980):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:607)

05-17 18:43:49.202: E/WindowManager(4980): at dalvik.system.NativeStart.main(Native Method)

我是这方面的初学者,任何人都可以让我知道这个错误是什么意思吗?

4

2 回答 2

2

如日志:

原因:java.lang.RuntimeException:无法在未调用 Looper.prepare() 的线程内创建处理程序

因为您正在尝试显示来自非 ui Thread 方法手段的ToastMessages 。doInBackground为避免此错误,您需要返回始终success在UI 线程上运行的位置。doInBackgroundonPostExecute

//create ending process 
protected void onPostExecute(String string) {

    // dismiss the dialog once got all details  
    pDialog.dismiss();
    //show Toast message here....
}
于 2013-05-17T11:06:15.790 回答
2

问题:

你得到以下异常:

原因:java.lang.RuntimeException:无法在未调用 Looper.prepare() 的线程内创建处理程序

只是因为下面的代码:

//if the success is equals to 1
if(success == 1){

      //toast successful message to user
      Toast.makeText(getApplicationContext(), json.getString(TAG_MESSAGE) , Toast.LENGTH_SHORT).show();
 }else{
      //toast error message to user
      Toast.makeText(getApplicationContext(), json.getString(TAG_MESSAGE) , Toast.LENGTH_SHORT).show();
 }

你为什么会得到这个异常?

您正在尝试显示来自非 UI 线程的 doInBackground() 方法的 Toast 消息。

解决方案:

每当您想在使用 进行长时间运行的过程时显示/更新 UI 时AsyncTask,您可以实现以下任一解决方案:

  1. 更新方法内的 UI onPostExecute()。// 标准方式
  2. 在内部实现runOnUiThread()和更新 UIdoInBackground()
于 2013-05-17T11:15:34.060 回答