android错误“无法在未调用looper.prepare的线程内创建处理程序” [重复]

Posted

技术标签:

【中文标题】android错误“无法在未调用looper.prepare的线程内创建处理程序” [重复]【英文标题】:android error "cant create handler inside thread that has not called looper.prepare" [duplicate] 【发布时间】:2014-03-03 01:05:25 【问题描述】:

我有一个名为 ShareId 的对话框片段和一个名为 SendMapDataService。当我从 ShareId 调用 SendMapDataService 出现错误无法在尚未调用的线程内创建处理程序 looper.prepare....

共享 ID

    package dialog;

    import com.rosaloves.bitlyj.Url;
    import static com.rosaloves.bitlyj.Bitly.*;

    import java.util.Calendar;

    import updatedata.GPSTracker;
    import updatedata.SendMapDataService;

    import com.example.map.LocationSendActivity;
    import com.example.map.R;

    import android.app.ProgressDialog;
    import android.content.Intent;
    import android.net.Uri;
    import android.os.AsyncTask;
    import android.os.Bundle;
    import android.support.v4.app.DialogFragment;
    import android.util.Log;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.Toast;

    public class ShareId extends DialogFragment 
        Button ok,cancel;
        public static EditText et;
        private double latt,lngt;
        public static String sid,lat,lng,time; 
        ProgressDialog pDialog;
        GPSTracker gps;

        public void onCreate(Bundle savedInstanceState)
            super.onCreate(savedInstanceState);
        

        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) 
            View V = inflater.inflate(R.layout.shareid, container, false);
            ok=(Button)V.findViewById(R.id.button1);
            cancel=(Button)V.findViewById(R.id.button2);
            et=(EditText)V.findViewById(R.id.editText1);
            getDialog().setTitle("Enter Share_id");

            ok.setOnClickListener(new View.OnClickListener() 

                @Override
                public void onClick(View v) 
                    // TODO Auto-generated method stub
                sid=et.getText().toString();
                if(sid.length() == 0 )
                    Toast.makeText(getActivity(),"Please enter share_id",Toast.LENGTH_SHORT).show();
                else
                    new ShareTask().execute();
                    
                
            );

            cancel.setOnClickListener(new View.OnClickListener() 

                @Override
                public void onClick(View v) 
                    // TODO Auto-generated method stub
                    getDialog().dismiss();
                
            ); 
         return V;      
        

         class ShareTask extends AsyncTask<String, String, String>

                StringBuffer sbf2=new StringBuffer();
                boolean b=false;
                int ch;
                protected void onPreExecute() 
                    super.onPreExecute();
                    pDialog = new ProgressDialog(getActivity());
                    pDialog.setMessage("Loading Application. Please wait...");
                    pDialog.setIndeterminate(false);
                    pDialog.setCancelable(false);
                    pDialog.show();
                
                @Override
                protected String doInBackground(String... params) 
                    // TODO Auto-generated method stub

                    // Create download Url
                    Url url = as("adeveloper962", "R_38e071119c3048db892f3aca82b03392")
                            .call(shorten("http://map.rhaasoft.net//locationfile/download.php")); 
                    String ul = url.getShortUrl();
                    sbf2.append("Click for download LocationMapping file"+" "+ul+"\n");
                    //Create location Url
                    gps = new GPSTracker(getActivity());
                     if(gps.canGetLocation())
                         Log.e("Shareid", "hello");
                            b=true;
                            //get Time
                            time= java.text.DateFormat.getDateTimeInstance().format(Calendar.getInstance().getTime());
                            //get latitude longitude
                            latt = gps.getLatitude();
                            lat=String.valueOf(latt);
                            lngt= gps.getLongitude();
                            lng=String.valueOf(lngt);
                            //add link
                            Uri.Builder ur=Uri.parse("http://myapp.com/?").buildUpon();
                            ur.appendQueryParameter("la", lat);
                            ur.appendQueryParameter("ln", lng);
                            ur.appendQueryParameter("ti", time);
                            ur.appendQueryParameter("id", sid);
                            ur.build(); 
                            //shorting url
                            Url url1 = as("adeveloper962", "R_38e071119c3048db892f3aca82b03392")
                                    .call(shorten(ur.toString())); 
                            String ul1 = url1.getShortUrl();
                            //append
                            sbf2.append("Click for show location"+" "+ul1); 
                        else
                             b=false;
                        
                    return null;
                

                protected void onPostExecute(String file_url) 
                    pDialog.dismiss();
                    getActivity().runOnUiThread(new Runnable() 
                        public void run() 
                            if(b == true)
                                getDialog().dismiss();
                                Intent intent = new Intent(Intent.ACTION_SEND);
                                intent.setType("text/plain");
                                intent.putExtra(Intent.EXTRA_SUBJECT, "Location Shareing");
                                intent.putExtra(Intent.EXTRA_TEXT, sbf2.toString());
                                startActivity(Intent.createChooser(intent, "Select Application for share"));

                                //Send continue data
                                ch=LocationSendActivity.state;
                                if(ch == 0 || ch ==1)
                                    LocationSendActivity.i=1;
                                    LocationSendActivity.u_id=sid;
                                    getActivity().startService(new Intent(getActivity(),SendMapDataService.class));
                                else
                                    LocationSendActivity.i=0;
                                    getActivity().stopService(new Intent(getActivity(),SendMapDataService.class));
                                
                            else
                                getDialog().dismiss();
                                gps.showSettingsAlert();
                            
                        
                    );
                

             


发送地图数据服务..

    package updatedata;

import java.util.Calendar;

import org.json.JSONException;
import org.json.JSONObject;

import com.example.map.FunctionCall;
import com.example.map.LocationSendActivity;

import android.app.Service;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;

public class SendMapDataService extends Service  
    private Handler handler;
    private String id1,lat1,lng1,time1;
    private double lat,lng;
    GPSTracker gps;
    private long total,val,min;


    @Override
    public IBinder onBind(Intent intent) 
        // TODO Auto-generated method stub
        gps=new GPSTracker(getApplicationContext());
        return null;
    

    public int onStartCommand(Intent intent, int flags, int startId) 

        id1=LocationSendActivity.u_id;
        // Log.e("Myid", String.valueOf(LocationSendActivity.u_id));

        // get time from time interval
        if(min == 1)
         val=15;    
        else if(min == 2)
         val=30;    
        else if(min == 3)
         val=60;    
        else if(min == 4)
         val=5*60;  
        else if(min == 5)
         val=10*60; 
        
        else
             val=15;    
            
        total=(long) (val*1000);
        // Log.e("Seconds", String.valueOf(total));

        // Start handler
        handler=new Handler();
        handler.postDelayed(runn, 1000);
       // Looper.loop();

        return START_STICKY;
        

    Runnable runn = new Runnable() 
           @Override
           public void run() 
               gps=new GPSTracker(getApplicationContext());
               if(gps.canGetLocation())
               lat = gps.getLatitude();
               lng = gps.getLongitude();
               time1=java.text.DateFormat.getDateTimeInstance().format(Calendar.getInstance().getTime());
               lat1=String.valueOf(lat);
               lng1=String.valueOf(lng);

               new SendUpdatedData(id1,lat1,lng1,time1).execute(); 
               handler.postDelayed(this, total);
               else
                   gps.showSettingsAlert();   
               
           
        ;

    public void onDestroy() 
        super.onDestroy();
        handler.removeCallbacks(runn,null);
        Toast.makeText(this, "Data Send Service Destroyed", Toast.LENGTH_LONG).show();
    


    class SendUpdatedData extends AsyncTask<String, String, String>
        String id2,lat2,lng2,time2;
        int success,val,update;

        public SendUpdatedData(String id, String lat,String lng,String time) 
            // TODO Auto-generated constructor stub
            this.id2=id;
            this.lat2=lat;
            this.lng2=lng;
            this.time2=time;
        

        protected void onPreExecute()
            super.onPreExecute();
        

        @Override
        protected String doInBackground(String... params) 
            // TODO Auto-generated method stub
            FunctionCall fc=new FunctionCall();
            JSONObject jo=fc.sendUpdateData(id2,lat2,lng2,time2);
            try
                 success=jo.getInt("success");
                 update=jo.getInt("update");

            catch(JSONException e)
                e.printStackTrace();
            
            return null;
        

        protected void onPostExecute(String file_url)

            if (success==1)
                if(update == 1)
                    Toast.makeText(getApplication(),"Data Updated", Toast.LENGTH_SHORT).show();
                else
                    Toast.makeText(getApplication(),"New Data Inserted", Toast.LENGTH_SHORT).show();
                
               
            else   
                Toast.makeText(getApplication(),"Data Not Send", Toast.LENGTH_SHORT).show();
            

        

    



LogCat....

02-06 12:16:43.740: W/System.err(15622): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
02-06 12:16:43.740: W/System.err(15622):    at android.os.Handler.<init>(Handler.java:121)
02-06 12:16:43.740: W/System.err(15622):    at android.location.LocationManager$ListenerTransport$1.<init>(LocationManager.java:137)
02-06 12:16:43.750: W/System.err(15622):    at android.location.LocationManager$ListenerTransport.<init>(LocationManager.java:137)
02-06 12:16:43.750: W/System.err(15622):    at android.location.LocationManager._requestLocationUpdates(LocationManager.java:708)
02-06 12:16:43.750: W/System.err(15622):    at android.location.LocationManager.requestLocationUpdates(LocationManager.java:630)
02-06 12:16:43.750: W/System.err(15622):    at updatedata.GPSTracker.getLocation(GPSTracker.java:65)
02-06 12:16:43.750: W/System.err(15622):    at updatedata.GPSTracker.<init>(GPSTracker.java:44)
02-06 12:16:43.750: W/System.err(15622):    at dialog.ShareId$ShareTask.doInBackground(ShareId.java:96)
02-06 12:16:43.750: W/System.err(15622):    at dialog.ShareId$ShareTask.doInBackground(ShareId.java:1)
02-06 12:16:43.750: W/System.err(15622):    at android.os.AsyncTask$2.call(AsyncTask.java:185)
02-06 12:16:43.750: W/System.err(15622):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
02-06 12:16:43.750: W/System.err(15622):    at java.util.concurrent.FutureTask.run(FutureTask.java:137)
02-06 12:16:43.750: W/System.err(15622):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
02-06 12:16:43.750: W/System.err(15622):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
02-06 12:16:43.750: W/System.err(15622):    at java.lang.Thread.run(Thread.java:1096)

【问题讨论】:

请先搜索再询问。这是 many 答案的常见错误。无需提出新问题。 【参考方案1】:

只需在出现异常的行上方调用Looper.prepare();..

【讨论】:

感谢 Ankit,它正在工作........ Only one Looper may be created per thread

以上是关于android错误“无法在未调用looper.prepare的线程内创建处理程序” [重复]的主要内容,如果未能解决你的问题,请参考以下文章

Flutter Android Build Gradle错误配置根项目'android'?

Android Studio编译错误总结

android为啥会有以下错误?

Android Studio Android 资源链接失败错误.. AAPT:错误:找不到资源 android:attr/lStar。在 values.xml 105

无法构建 CastVideos-android,错误:路径名错误

Android 地图错误“找不到类 'android.app.AppOpsManager'”