2016-03-26 18 views
0

Ich habe ein service die String of Json-MainActivity passieren:Android - Fehler beim Empfang der Broadcast-Absicht?

GetSubjects.class:

public class GetSubjects extends Service { 
    String URL = "http://webservice.jim.com/YYY/XXXX.asmx"; 
    String Webresponse = "IS NULL ?"; 
    int scode = 1597536485; 
    String result; 
    public final static String MY_ACTION = "MY_ACTION"; 
    @Nullable 
    @Override 
    public IBinder onBind(Intent intent) { 
     return null; 
    } 

    @Override 
    public int onStartCommand(final Intent intent, int flags, final int startId) { 
     Runnable r = new Runnable() { 
      @Override 
      public void run() { 
       handleStart(intent, startId); 
      } 
     }; 
     Thread t = new Thread(r); 
     t.start(); 
     return START_NOT_STICKY; 
    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
    } 

    void handleStart(Intent intent, int startId) { 
     try { 
      Params_GetSubjects param = new Params_GetSubjects(scode); 
      result = new mGetSubjects().execute(param).get(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } catch (ExecutionException e) { 
      e.printStackTrace(); 
     } 
    } 

    public class mGetSubjects extends AsyncTask<Params_GetSubjects, String, String> { 

     String NAMESPACE = "http://tempuri.org/"; 
     String METHOD_NAME = "Get"; 
     String SOAP_ACTION = "http://tempuri.org/Get"; 
     @Override 
     protected String doInBackground(Params_GetSubjects... params) { 
      SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME); 
      request.addProperty("scode", params[0].Scode); 
      SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); 
      envelope.dotNet = true; 
      envelope.setOutputSoapObject(request); 
      HttpTransportSE conn = new HttpTransportSE(URL); 
      Object object; 
      try { 
       conn.call(SOAP_ACTION, envelope); 
       //SoapPrimitive response = (SoapPrimitive) envelope.getResponse(); 
       object = envelope.getResponse(); 
       Webresponse = object.toString(); 
      } catch (Exception e) { 
       e.printStackTrace(); 
       return "NULL"; 
      }finally { 
       ThreadFinish threadfinish = new ThreadFinish(); 
       threadfinish.start(); 
       return Webresponse; 
      } 
     } 
    } 
    public class ThreadFinish extends Thread{ 

     @Override 
     public void run() { 
      try { 
       Intent intent = new Intent(); 
       intent.setAction(MY_ACTION); 
       intent.putExtra("DATAPASSED", result); 
       sendBroadcast(intent); 
      }catch (Exception e){ 
       e.printStackTrace(); 
      }finally { 
       stopSelf(); 
      } 
     } 
    } 
} 

Hier ist meine MainActivity:

public class MainActivity extends AppCompatActivity { 
    MyReceiver myReceiver; 
    private RecyclerView.LayoutManager layoutManager; 
    private DrawerAdapter mDrawerAdapter; 
    private RecyclerView mRecyclerView; 
    List<DrawerItem> draweritemList; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     startService(new Intent(MainActivity.this, GetSubjects.class)); 

    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     // Handle action bar item clicks here. The action bar will 
     // automatically handle clicks on the Home/Up button, so long 
     // as you specify a parent activity in AndroidManifest.xml. 
     int id = item.getItemId(); 

     switch (id) { 
      case android.R.id.home: 
       mDrawerLayout.openDrawer(GravityCompat.START); 
       return true; 
      case R.id.action_settings: 
       return true; 
     } 

     return super.onOptionsItemSelected(item); 
    } 

    @Override 
    protected void onStart() { 
     myReceiver = new MyReceiver(); 
     IntentFilter intentFilter = new IntentFilter(); 
     intentFilter.addAction(GetSubjects.MY_ACTION); 
     registerReceiver(myReceiver, intentFilter); 
     super.onStart(); 
    } 

    @Override 
    protected void onStop() { 
     this.unregisterReceiver(myReceiver); 
     super.onStop(); 
    } 

    private class MyReceiver extends BroadcastReceiver { 

     @Override 
     public void onReceive(Context arg0, Intent arg1) { 

       String datapassed = arg1.getExtras().getString("DATAPASSED"); 
       Log.i("ASDQWRRYGH",datapassed); 

       draweritemList = JsonParser.parseFeed(datapassed); 

       for (int i=0;i < draweritemList.size();i++) 
       { 
        Log.i("ASDQWRRYGH",draweritemList.get(i).getTitle()); 
       } 



     } 

    } 
} 

Und hier ist mein JsonParer:

public class JsonParser { 
    public static List<DrawerItem> parseFeed(String content) { 
     try { 
      JSONObject jsonRootObject = new JSONObject(content); 
      JSONArray jsonArray = jsonRootObject.optJSONArray("Rows"); 
      List<DrawerItem> draweritemList = new ArrayList<>(); 
      for (int i = 0; i < jsonArray.length(); i++) { 
       JSONObject obj = jsonArray.getJSONObject(i); 
       DrawerItem draweritem = new DrawerItem(); 

       draweritem.setId(obj.getString("Id")); 
       draweritem.setTitle(obj.getString("Title")); 
       draweritemList.add(draweritem); 
      } 
      return draweritemList; 
     } catch (JSONException e) { 
      e.printStackTrace(); 
      return null; 
     } 
    } 
} 

oft bekommen mich aus dem Dienst führen aber mich oft brüllen Fehler bekommen, was kann ich tun ?:

enter image description here

+0

Sie bekommen Ihre Threads alle verwirrt, und Sie am Ende ausstrahlen, bevor 'Ergebnis' gesetzt wird. Sie brauchen nicht wirklich die 'ThreadFinish' Klasse. Die einfachste Lösung besteht darin, die Sendung nach der Zeile "result = ..." zu verschieben. Wirklich, du könntest/solltest alles in einen einzigen Thread setzen; Entweder in der 'AsyncTask', oder dem' Thread', der deine 'Runnable' ausführt. –

+1

Sehr, sehr Danke, mein Problem mit Ihrer Hilfe gelöst.Fügen Sie Ihre Antwort für die Abstimmung.Vielen Dank. –

Antwort

1

Sie drei in Ihrer Service Ausführung zusätzliche Threads haben; die AsyncTask und zwei Thread s. Die erste Thread führt Ihre AsyncTask aus, blockiert aber, weil Sie get() aufrufen, um den Rückgabewert der returnString zuzuweisen. Wenn die Netzwerktransaktion in der AsyncTask beendet ist, startet es eine andere Thread, um die Übertragung zu senden, und dies geschieht, bevor doInBackground() zurückgeben kann, um den Wert der returnString festzulegen, die gesendet wird, während es immer noch null ist.

Die einfachste Lösung ist es, den Broadcast nach der result = ... Zeile zu verschieben und die Klasse ThreadFinish loszuwerden.

Es könnte jedoch vorzuziehen sein, alles sequenziell in einem einzigen Thread auszuführen; Entweder in der AsyncTask, oder die Thread Ausführung Ihrer Runnable.

Verwandte Themen