2017-07-09 14 views
0

私のコードをリファクタリングして、Async Taskからローダーにコードを移動しようとしました。私はAndroid Performanceビデオシリーズを通じてローダーの利点を知りました。Loaders Android Performance ローダーが使用されている理由とそのクラスには何かがあります(理論)。しかし、私は作業コンセプトを理解することができないので、この貧しいコードを書いた。したがって、私はそれをデバッグすることもできません。 **編集:私はそれを動作させることができましたが、私はまだ間違った方法でそれを呼び出すと思います。アンドロイドのローダーを使用した単純なコードのエラー

新しいEarthquakeAsyncTaskLoader(この).forceLoad();

誰もがこの上で、私を助けることができる場合......... **

import android.content.AsyncTaskLoader; 
import android.content.Context; 
import android.content.Intent; 
import android.net.Uri; 
import android.os.Bundle; 
import android.support.v4.app.LoaderManager; 
import android.support.v4.content.Loader; 
import android.support.v7.app.AppCompatActivity; 
import android.view.View; 
import android.widget.AdapterView; 
import android.widget.ListView; 

import java.io.IOException; 
import java.util.ArrayList; 

public class EarthQuakeActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<ArrayList<EarthQuakes>> { 

ArrayList<EarthQuakes> earthquakes = null; 


@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_earth_quake); 

    getSupportLoaderManager().initLoader(1, null, this); 

}// End of onCreate 

@Override 
public Loader<ArrayList<EarthQuakes>> onCreateLoader(int id, Bundle args) { 

    **new EarthquakeAsyncTaskLoader(this).forceLoad();** 
} 

@Override 
public void onLoadFinished(Loader<ArrayList<EarthQuakes>> loader, ArrayList<EarthQuakes> data) { 
} 

@Override 
public void onLoaderReset(Loader<ArrayList<EarthQuakes>> loader) { 

} 


public class EarthquakeAsyncTaskLoader extends AsyncTaskLoader<ArrayList<EarthQuakes>> { 

    public EarthquakeAsyncTaskLoader(Context context) { 
     super(context); 
    } 


    @Override 
    protected void onStartLoading() { 
     // If the data is there, don't start again 
     if (earthquakes != null) { 
      deliverResult(earthquakes); 
     } else { 
      //Start the loader 
      forceLoad(); 
     } 
    } 

    @Override 
    public ArrayList<EarthQuakes> loadInBackground() { 
     // Get the populated list from QueryUtils java class 
     try { 
      // Here in QueryUtils, I am making an HTTP network call 
      // Thus it has to be done in a helper background thread 
      earthquakes = QueryUtils.getArrayList(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     return earthquakes; 
    } 


    @Override 
    public void deliverResult(ArrayList<EarthQuakes> data) { 

     // Feed the adapter with data and display it 
     ListView earthquakesList = (ListView) findViewById(R.id.listV); 
     final EarthQuakeAdapter adapter = new EarthQuakeAdapter(getApplicationContext(), data); 
     earthquakesList.setAdapter(adapter); 

     earthquakesList.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
      @Override 
      public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { 
       EarthQuakes currentEarthquake = adapter.getItem(i); 
       Uri earthquakeUri = Uri.parse(currentEarthquake.getUrl()); 

     // Create a new intent to view the earthquake URI 
       Intent websiteIntent = new Intent(Intent.ACTION_VIEW, earthquakeUri); 

     // Send the intent to launch a new activity 
       startActivity(websiteIntent); 
      } 
     }); 

    } 
}//End of Async Task Loader 


//EarthQuakes is my class. I don't think you'll need this. But anyway: 
public class EarthQuakes { 


    private double mMagnitude; 
    private String mLocationSmallText; 
    private String mLocationMainText; 
    private String mDateOfEarthquake; 
    private String mUrl; 


    // Default Constructor 
    public EarthQuakes(Double mag, String locationSmallText, String locationMainCityName, String dateE, String Url) { 
     this.mMagnitude = mag; 
     this.mLocationSmallText = locationSmallText; 
     this.mLocationMainText = locationMainCityName; 
     this.mDateOfEarthquake = dateE; 
     this.mUrl = Url; 
    } 


    // Public getters 
    public Double getMagnitude() { 
     return mMagnitude; 
    } 

    public String getLocationSmallTextEarthquake() { 
     return mLocationSmallText; 
    } 

    public String getLocationLargeTextEarthquake() { 
     return mLocationMainText; 
    } 

    public String getDateOfEarthquake() { 
     return mDateOfEarthquake; 
    } 

    public String getUrl() { 
     return mUrl; 
    } 

} 
+0

なぜあなたは、単に 'CursorLoader'を使用していけませんか? – pskink

+0

私はこのコンセプトを学ぼうとしているから.... – Aman

答えて

0

この代替でも動作します:

getSupportLoaderManager().initLoader(1, null, this).forceload();

をしかし、このローダーに関する問題を回避する方法としては、hereが挙げられます。 この問題は、CursorLoaderではないAsyncTaskLoaderを使用している場合に発生します。 onStartLoading()を実装し、forceLoad()を呼び出して処理する必要があります。問題のページに進むことを強くお勧めします。

あなたのアプリ全体の複数のローダーを使用していて、毎回onStartLoading()実装したくない場合。ここでは、あなたのアプリに含まれ、代わりに通常のAsyncTaskLoaderの本を継承できるカスタムローダークラスです:

WrappedAsyncTaskLoader.java(原作者:アレクサンダー・ブロム)

public abstract class WrappedAsyncTaskLoader<D> extends AsyncTaskLoader<D> { 

private D mData; 

/** 
* Constructor of <code>WrappedAsyncTaskLoader</code> 
* 
* @param context The {@link Context} to use. 
*/ 
public WrappedAsyncTaskLoader(Context context) { 
    super(context); 
} 

/** 
* {@inheritDoc} 
*/ 
@Override 
public void deliverResult(D data) { 
    if (!isReset()) { 
     this.mData = data; 
     super.deliverResult(data); 
    } else { 
     // An asynchronous query came in while the loader is stopped 
    } 
} 

/** 
* {@inheritDoc} 
*/ 
@Override 
protected void onStartLoading() { 
    super.onStartLoading(); 
    if (this.mData != null) { 
     deliverResult(this.mData); 
    } else if (takeContentChanged() || this.mData == null) { 
     forceLoad(); 
    } 
} 

/** 
* {@inheritDoc} 
*/ 
@Override 
protected void onStopLoading() { 
    super.onStopLoading(); 
    // Attempt to cancel the current load task if possible 
    cancelLoad(); 
} 

/** 
* {@inheritDoc} 
*/ 
@Override 
protected void onReset() { 
    super.onReset(); 
    // Ensure the loader is stopped 
    onStopLoading(); 
    this.mData = null; 
} 
} 
関連する問題